Merge tag 'LA.VENDOR.13.2.0.r1-22400-KAILUA.QSSI14.0' into staging/lineage-21.0_merge-LA.VENDOR.13.2.0.r1-22400-KAILUA.QSSI14.0

LA.VENDOR.13.2.0.r1-22400-KAILUA.QSSI14.0

# By Jagadeesh Ponduru (3) and others
# Via Linux Build Service Account (3) and others
* tag 'LA.VENDOR.13.2.0.r1-22400-KAILUA.QSSI14.0':
  msm: ipa3: Adding changes to check pointer null or not
  msm: ipa: Null terminated interface name string argument received from ioctl
  msm: ipa3: unvote proxy clock if no uC loading in APQ
  msm: ipa3: Fix to restart tasklet for pending packets
  msm: ipa4: Fix to exit from tasklet after processing max packet

Change-Id: I1a137edd807332c4c644513c8468db8fa321c52c
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index 5ffed59..d20b59e 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -8593,7 +8593,7 @@
 	if (ipa3_ctx->platform_type == IPA_PLAT_TYPE_APQ &&
 		ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_VIRTUAL &&
 		ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_EMULATION &&
-		ipa3_ctx->ipa_config_is_apq_uc_load) {
+		!ipa3_ctx->ipa_config_is_apq_no_uc_load) {
 
 		IPADBG("Loading IPA uC via PIL or MDT\n");
 
@@ -8622,6 +8622,10 @@
 		IPADBG("IPA uC loading succeeded\n");
 		ipa3_proxy_clk_unvote();
 	}
+
+	/*In case of no modem and no uc loading in apq, remove the proxy vote here.*/
+	if(ipa3_ctx->ipa_config_is_apq_no_uc_load)
+		ipa3_proxy_clk_unvote();
 }
 
 static void ipa_fw_load_sm_handle_event(enum ipa_fw_load_event ev)
@@ -9299,7 +9303,7 @@
                         resource_p->ipa_gen_rx_cmn_temp_pool_sz_factor);
 	ipa3_ctx->ipa_config_is_auto = resource_p->ipa_config_is_auto;
 	ipa3_ctx->ipa_config_is_apq_dma = resource_p->ipa_config_is_apq_dma;
-	ipa3_ctx->ipa_config_is_apq_uc_load = resource_p->ipa_config_is_apq_uc_load;
+	ipa3_ctx->ipa_config_is_apq_no_uc_load = resource_p->ipa_config_is_apq_no_uc_load;
 	ipa3_ctx->ipa_mhi_proxy = resource_p->ipa_mhi_proxy;
 	ipa3_ctx->max_num_smmu_cb = resource_p->max_num_smmu_cb;
 	ipa3_ctx->hw_type_index = ipa3_get_hw_type_index();
@@ -10265,7 +10269,7 @@
 	ipa_drv_res->ipa_gpi_event_rp_ddr = false;
 	ipa_drv_res->ipa_config_is_auto = false;
 	ipa_drv_res->ipa_config_is_apq_dma = false;
-	ipa_drv_res->ipa_config_is_apq_uc_load = false;
+	ipa_drv_res->ipa_config_is_apq_no_uc_load = false;
 	ipa_drv_res->max_num_smmu_cb = IPA_SMMU_CB_MAX;
 	ipa_drv_res->ipa_endp_delay_wa_v2 = false;
 	ipa_drv_res->use_tput_est_ep = false;
@@ -10418,11 +10422,11 @@
 		ipa_drv_res->ipa_config_is_apq_dma
 		? "True" : "False");
 
-	ipa_drv_res->ipa_config_is_apq_uc_load =
+	ipa_drv_res->ipa_config_is_apq_no_uc_load =
 		of_property_read_bool(pdev->dev.of_node,
-		"qcom,ipa-config-is-apq-uc-load");
-	IPADBG(": ipa-config-is-apq-uc-load = %s\n",
-		ipa_drv_res->ipa_config_is_apq_uc_load
+		"qcom,ipa-config-is-apq-no-uc-load");
+	IPADBG(": ipa-config-is-apq-no-uc-load = %s\n",
+		ipa_drv_res->ipa_config_is_apq_no_uc_load
 		? "True" : "False");
 
 	ipa_drv_res->ipa_wan_skb_page =
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
index 56ddeb9..098b87c 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
@@ -102,6 +102,8 @@
 
 #define IPA_QMAP_ID_BYTE 0
 
+#define IPA_TX_MAX_DESC (50)
+
 #define IPA_MEM_ALLOC_RETRY 5
 
 static int ipa3_tx_switch_to_intr_mode(struct ipa3_sys_context *sys);
@@ -391,6 +393,15 @@
 	ipa3_write_done_common(sys, tx_pkt);
 }
 
+static void ipa3_tasklet_schd_work(struct work_struct *work)
+{
+	struct ipa3_sys_context *sys;
+
+	sys = container_of(work, struct ipa3_sys_context, tasklet_work);
+	if (atomic_read(&sys->xmit_eot_cnt))
+		tasklet_schedule(&sys->tasklet);
+}
+
 /**
  * ipa_write_done() - this function will be (eventually) called when a Tx
  * operation is complete
@@ -408,6 +419,7 @@
 	struct ipa3_sys_context *sys;
 	struct ipa3_tx_pkt_wrapper *this_pkt;
 	bool xmit_done = false;
+	unsigned int max_tx_pkt = 0;
 
 	sys = (struct ipa3_sys_context *)data;
 	spin_lock_bh(&sys->spinlock);
@@ -419,11 +431,22 @@
 			spin_unlock_bh(&sys->spinlock);
 			ipa3_write_done_common(sys, this_pkt);
 			spin_lock_bh(&sys->spinlock);
+			max_tx_pkt++;
 			if (xmit_done)
 				break;
 		}
+		/* If TX packets processing continuously in tasklet other
+		 * softirqs are not able to run on that core which is leading
+		 * to watchdog bark. For avoiding these scenarios exit from
+		 * tasklet after reaching max limit.
+		 */
+		 if (max_tx_pkt >= IPA_TX_MAX_DESC)
+			 break;
 	}
 	spin_unlock_bh(&sys->spinlock);
+
+	if (max_tx_pkt >= IPA_TX_MAX_DESC)
+		queue_work(sys->tasklet_wq, &sys->tasklet_work);
 }
 
 static int ipa3_napi_poll_tx_complete(struct ipa3_sys_context *sys, int budget)
@@ -1393,6 +1416,8 @@
 
 	sys = (struct ipa3_sys_context *)data;
 
+	if(sys->page_recycle_repl == NULL)
+		return;
 	INIT_LIST_HEAD(&temp_head);
 	spin_lock_bh(&sys->common_sys->spinlock);
 	list_for_each_entry_safe(rx_pkt, tmp,
@@ -1525,6 +1550,18 @@
 			goto fail_wq2;
 		}
 
+		snprintf(buff, IPA_RESOURCE_NAME_MAX, "ipataskletwq%d",
+				sys_in->client);
+
+		ep->sys->tasklet_wq = alloc_workqueue(buff,
+				WQ_MEM_RECLAIM | WQ_UNBOUND | WQ_SYSFS, 1);
+		if (!ep->sys->tasklet_wq) {
+			IPAERR("failed to create rep wq for client %d\n",
+					sys_in->client);
+			result = -EFAULT;
+			goto fail_wq_tasklet;
+		}
+
 		snprintf(buff, IPA_RESOURCE_NAME_MAX, "ipafreepagewq%d",
 				sys_in->client);
 
@@ -1596,9 +1633,12 @@
 		tx_completion_func = &ipa3_aux_napi_tx_complete;
 
 	atomic_set(&ep->sys->xmit_eot_cnt, 0);
-	if (IPA_CLIENT_IS_PROD(sys_in->client))
+	if (IPA_CLIENT_IS_PROD(sys_in->client)) {
 		tasklet_init(&ep->sys->tasklet, ipa3_tasklet_write_done,
 				(unsigned long) ep->sys);
+		INIT_WORK(&ep->sys->tasklet_work,
+			ipa3_tasklet_schd_work);
+	}
 	if (sys_in->client == IPA_CLIENT_APPS_WAN_LOW_LAT_CONS)
 		tasklet_init(&ep->sys->tasklet, ipa3_tasklet_rx_notify,
 				(unsigned long) ep->sys);
@@ -1910,6 +1950,8 @@
 	if (ep->sys->freepage_wq)
 		destroy_workqueue(ep->sys->freepage_wq);
 fail_wq3:
+	destroy_workqueue(ep->sys->tasklet_wq);
+fail_wq_tasklet:
 	destroy_workqueue(ep->sys->repl_wq);
 fail_wq2:
 	destroy_workqueue(ep->sys->wq);
@@ -2118,7 +2160,8 @@
 	}
 	if (ep->sys->repl_wq)
 		flush_workqueue(ep->sys->repl_wq);
-
+	if (ep->sys->tasklet_wq)
+		flush_workqueue(ep->sys->tasklet_wq);
 	if (ep->sys->repl_hdlr == ipa3_replenish_rx_page_recycle) {
 		cancel_delayed_work_sync(&ep->sys->common_sys->freepage_work);
 		tasklet_kill(&ep->sys->common_sys->tasklet_find_freepage);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index 36223f1..e2fc6ff 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -1220,6 +1220,7 @@
 	struct list_head pending_pkts[GSI_VEID_MAX];
 	atomic_t xmit_eot_cnt;
 	struct tasklet_struct tasklet;
+	struct work_struct tasklet_work;
 	bool skip_eot;
 	u32 eob_drop_cnt;
 	struct napi_struct napi_tx;
@@ -1253,6 +1254,7 @@
 	struct workqueue_struct *freepage_wq;
 	struct delayed_work freepage_work;
 	struct tasklet_struct tasklet_find_freepage;
+	struct workqueue_struct *tasklet_wq;
 	/* ordering is important - other immutable fields go below */
 };
 
@@ -2271,7 +2273,7 @@
  * @ipa_wdi2: using wdi-2.0
  * @ipa_config_is_auto: is this AUTO use case
  * @ipa_config_is_apq_dma: this is for APQ DMA use case
- * @ipa_config_is_apq_uc_load: this is for APQ uC load use case
+ * @ipa_config_is_apq_no_uc_load: flag which configures to load uC or not in APQ
  * @ipa_fltrt_not_hashable: filter/route rules not hashable
  * @use_xbl_boot: use xbl loading for IPA FW
  * @use_64_bit_dma_mask: using 64bits dma mask
@@ -2409,7 +2411,7 @@
 	bool ipa_wdi2;
 	bool ipa_config_is_auto;
 	bool ipa_config_is_apq_dma;
-	bool ipa_config_is_apq_uc_load;
+	bool ipa_config_is_apq_no_uc_load;
 	bool ipa_wdi2_over_gsi;
 	bool ipa_wdi3_over_gsi;
 	bool ipa_endp_delay_wa;
@@ -2627,7 +2629,7 @@
 	bool ipa_wdi2;
 	bool ipa_config_is_auto;
 	bool ipa_config_is_apq_dma;
-	bool ipa_config_is_apq_uc_load;
+	bool ipa_config_is_apq_no_uc_load;
 	bool ipa_wdi2_over_gsi;
 	bool ipa_wdi3_over_gsi;
 	bool ipa_fltrt_not_hashable;
diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
index d663da6..5b9218b 100644
--- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
@@ -6302,6 +6302,10 @@
 	int rmnet_index;
 
 	mux_channel = rmnet_ipa3_ctx->mux_channel;
+
+	/* prevent string buffer overflows */
+	data->if_name[IPA_RESOURCE_NAME_MAX-1] = '\0';
+
 	rmnet_index =
 		find_vchannel_name_index(data->if_name);