Merge branch 'LA.UM.9.12.C10.11.00.00.840.201' via branch 'qcom-msm-4.19-7250' into android-msm-pixel-4.19

Bug: 210578498
Signed-off-by: JohnnLee <johnnlee@google.com>
Change-Id: I33fd3a05def6d780604bc7dcff90006ca525061f
diff --git a/drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c b/drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c
index b262b23..2f1f1be 100644
--- a/drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c
+++ b/drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c
@@ -3730,11 +3730,6 @@
 		TX_CONTEXT_DESC_TDES3_OWN_MLF_WR(
 			TX_CONTEXT_DESC->TDES3, 0x1);
 
-		/* DMA uses the MSS value programed in DMA_CR if driver
-		 * doesn't provided the CONTEXT descriptor
-		 */
-		DMA_CR_MSS_UDFWR(QINX, tx_pkt_features->mss);
-
 		tx_desc_data->default_mss = tx_pkt_features->mss;
 
 		original_start_index = tx_desc_data->cur_tx;
diff --git a/drivers/emac-dwc-eqos/DWC_ETH_QOS_drv.c b/drivers/emac-dwc-eqos/DWC_ETH_QOS_drv.c
index fda72a8..c467561 100644
--- a/drivers/emac-dwc-eqos/DWC_ETH_QOS_drv.c
+++ b/drivers/emac-dwc-eqos/DWC_ETH_QOS_drv.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019,2021 The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -6802,8 +6802,18 @@
 	DBGPR("-->DWC_ETH_QOS_program_dcb_algorithm\n");
 
 	if (copy_from_user(&l_dcb_struct, u_dcb_struct,
-			   sizeof(struct DWC_ETH_QOS_dcb_algorithm)))
-		dev_alert(&pdata->pdev->dev, "Failed to fetch DCB Struct info from user\n");
+			   sizeof(struct DWC_ETH_QOS_dcb_algorithm))) {
+		dev_alert(&pdata->pdev->dev,
+			  "Failed to fetch DCB Struct info from user\n");
+		return;
+	}
+
+	if (l_dcb_struct.qinx >= DWC_ETH_QOS_TX_QUEUE_CNT) {
+		dev_alert(&pdata->pdev->dev,
+			  "Invaild queue number[%u] in DCB Struct from user\n",
+			  l_dcb_struct.qinx);
+		return;
+	}
 
 	hw_if->set_tx_queue_operating_mode(l_dcb_struct.qinx,
 		(UINT)l_dcb_struct.op_mode);
@@ -6839,8 +6849,10 @@
 	DBGPR("-->DWC_ETH_QOS_program_avb_algorithm\n");
 
 	if (copy_from_user(&l_avb_struct, u_avb_struct,
-			   sizeof(struct DWC_ETH_QOS_avb_algorithm)))
+			   sizeof(struct DWC_ETH_QOS_avb_algorithm))) {
 		dev_alert(&pdata->pdev->dev, "Failed to fetch AVB Struct info from user\n");
+		return;
+	}
 
 	if (pdata->speed == SPEED_1000)
 		avb_params = &l_avb_struct.speed1000params;
@@ -6849,10 +6861,16 @@
 
 	/*Application uses 1 for CLASS A traffic and 2 for CLASS B traffic
 	  Configure right channel accordingly*/
-	if (l_avb_struct.qinx == 1)
+	if (l_avb_struct.qinx == 1) {
 		l_avb_struct.qinx = CLASS_A_TRAFFIC_TX_CHANNEL;
-	else if (l_avb_struct.qinx == 2)
+	} else if (l_avb_struct.qinx == 2) {
 		l_avb_struct.qinx = CLASS_B_TRAFFIC_TX_CHANNEL;
+	} else {
+		dev_alert(&pdata->pdev->dev,
+			  "Invalid queue number[%u] in AVB struct from user\n",
+			  l_avb_struct.qinx);
+		return;
+	}
 
 	hw_if->set_tx_queue_operating_mode(l_avb_struct.qinx,
 		(UINT)l_avb_struct.op_mode);
diff --git a/drivers/rmnet/shs/rmnet_shs.h b/drivers/rmnet/shs/rmnet_shs.h
index 99ca7e4..5c28537 100644
--- a/drivers/rmnet/shs/rmnet_shs.h
+++ b/drivers/rmnet/shs/rmnet_shs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -106,6 +106,7 @@
 	u8 dl_ind_state;
 	u8 map_mask;
 	u8 map_len;
+	u8 ff_flag;
 
 };
 
@@ -178,6 +179,8 @@
 	RMNET_SHS_FLUSH_WQ_FB_FLUSH,
 	RMNET_SHS_FLUSH_WQ_CORE_FLUSH,
 	RMNET_SHS_FLUSH_PSH_PKT_FLUSH,
+	RMNET_SHS_FLUSH_WQ_FB_FF_FLUSH,
+	RMNET_SHS_FLUSH_Z_QUEUE_FLUSH,
 	RMNET_SHS_FLUSH_MAX_REASON
 };
 
diff --git a/drivers/rmnet/shs/rmnet_shs_main.c b/drivers/rmnet/shs/rmnet_shs_main.c
index c65298b..c46cc67 100755
--- a/drivers/rmnet/shs/rmnet_shs_main.c
+++ b/drivers/rmnet/shs/rmnet_shs_main.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -83,6 +83,20 @@
 module_param(rmnet_shs_byte_store_limit, uint, 0644);
 MODULE_PARM_DESC(rmnet_shs_byte_store_limit, "Maximum byte module will park");
 
+
+unsigned int rmnet_shs_in_count = 0;
+module_param(rmnet_shs_in_count, uint, 0644);
+MODULE_PARM_DESC(rmnet_shs_in_count, "SKb in count");
+
+unsigned int rmnet_shs_out_count = 0;
+module_param(rmnet_shs_out_count, uint, 0644);
+MODULE_PARM_DESC(rmnet_shs_out_count, "SKb out count");
+
+unsigned int rmnet_shs_wq_fb_limit = 10;
+module_param(rmnet_shs_wq_fb_limit, uint, 0644);
+MODULE_PARM_DESC(rmnet_shs_wq_fb_limit, "Final fb timer");
+
+
 unsigned int rmnet_shs_pkts_store_limit __read_mostly = 2100 * 8;
 module_param(rmnet_shs_pkts_store_limit, uint, 0644);
 MODULE_PARM_DESC(rmnet_shs_pkts_store_limit, "Maximum pkts module will park");
@@ -370,6 +384,8 @@
 	struct rmnet_priv *priv;
 	struct napi_struct *napi;
 
+	rmnet_shs_out_count++;
+
 	SHS_TRACE_LOW(RMNET_SHS_DELIVER_SKB, RMNET_SHS_DELIVER_SKB_START,
 			    0xDEF, 0xDEF, 0xDEF, 0xDEF, skb, NULL);
 
@@ -392,6 +408,7 @@
 
 	SHS_TRACE_LOW(RMNET_SHS_DELIVER_SKB, RMNET_SHS_DELIVER_SKB_START,
 			    0xDEF, 0xDEF, 0xDEF, 0xDEF, skb, NULL);
+	rmnet_shs_out_count++;
 
 	priv = netdev_priv(skb->dev);
 	gro_cells_receive(&priv->gro_cells, skb);
@@ -460,6 +477,7 @@
 	SHS_TRACE_LOW(RMNET_SHS_DELIVER_SKB, RMNET_SHS_DELIVER_SKB_START,
 			    0x1, 0xDEF, 0xDEF, 0xDEF, in_skb, NULL);
 
+	rmnet_shs_out_count++;
 	segs = rmnet_shs_skb_partial_segment(in_skb, segs_per_skb);
 
 	if (segs == NULL) {
@@ -822,6 +840,7 @@
 	int new_cpu;
 	struct rmnet_shs_cpu_node_s *cpun;
 	u8 map = rmnet_shs_cfg.map_mask;
+	u32 old_cpu_qlen;
 
 	cpu_map_index = rmnet_shs_get_hash_map_idx_to_stamp(node);
 	do {
@@ -848,9 +867,9 @@
 		cur_cpu_qhead = rmnet_shs_get_cpu_qhead(node->map_cpu);
 		node_qhead = node->queue_head;
 		cpu_num = node->map_cpu;
+		old_cpu_qlen = GET_PQUEUE(cpu_num).qlen + GET_IQUEUE(cpu_num).qlen;
 
-		if ((cur_cpu_qhead >= node_qhead) ||
-		    (force_flush)) {
+		if ((cur_cpu_qhead >= node_qhead) || force_flush || (!old_cpu_qlen && ++rmnet_shs_flush_reason[RMNET_SHS_FLUSH_Z_QUEUE_FLUSH])) {
 			if (rmnet_shs_switch_cores) {
 
 				/* Move the amount parked to other core's count
@@ -892,6 +911,7 @@
 				cpun = &rmnet_shs_cpu_node_tbl[node->map_cpu];
 				rmnet_shs_update_cpu_proc_q_all_cpus();
 				node->queue_head = cpun->qhead;
+
 				rmnet_shs_cpu_node_move(node,
 							&cpun->node_list_id,
 							cpu_num);
@@ -1281,7 +1301,7 @@
 
 	if ((rmnet_shs_cfg.num_bytes_parked <= 0) ||
 	    (rmnet_shs_cfg.num_pkts_parked <= 0)) {
-
+		rmnet_shs_cfg.ff_flag = 0;
 		rmnet_shs_cfg.num_bytes_parked = 0;
 		rmnet_shs_cfg.num_pkts_parked = 0;
 		rmnet_shs_cfg.is_pkt_parked = 0;
@@ -1290,9 +1310,7 @@
 			if (hrtimer_active(&rmnet_shs_cfg.hrtimer_shs))
 				hrtimer_cancel(&rmnet_shs_cfg.hrtimer_shs);
 		}
-
 	}
-
 }
 
 void rmnet_shs_flush_table(u8 flsh, u8 ctxt)
@@ -1314,6 +1332,12 @@
 			hrtimer_start(&rmnet_shs_cfg.hrtimer_shs,
 				ns_to_ktime(rmnet_shs_timeout * NS_IN_MS),
 				HRTIMER_MODE_REL);
+		if (rmnet_shs_fall_back_timer &&
+		    rmnet_shs_cfg.num_bytes_parked &&
+		    rmnet_shs_cfg.num_pkts_parked){
+				rmnet_shs_cfg.ff_flag++;
+		}
+
 		}
 		rmnet_shs_flush_reason[RMNET_SHS_FLUSH_WQ_FB_FLUSH]++;
 	}
@@ -1389,23 +1413,27 @@
  */
 static void rmnet_flush_buffered(struct work_struct *work)
 {
-	u8 is_force_flush = 0;
 
 	SHS_TRACE_HIGH(RMNET_SHS_FLUSH,
-			     RMNET_SHS_FLUSH_DELAY_WQ_START, is_force_flush,
+			     RMNET_SHS_FLUSH_DELAY_WQ_START, rmnet_shs_cfg.ff_flag,
 			     rmnet_shs_cfg.force_flush_state, 0xDEF,
 			     0xDEF, NULL, NULL);
 
 	if (rmnet_shs_cfg.num_pkts_parked &&
 	   rmnet_shs_cfg.force_flush_state == RMNET_SHS_FLUSH_ON) {
 		local_bh_disable();
-		rmnet_shs_flush_table(is_force_flush,
+		if (rmnet_shs_cfg.ff_flag >= rmnet_shs_wq_fb_limit) {
+			rmnet_shs_flush_reason[RMNET_SHS_FLUSH_WQ_FB_FF_FLUSH]++;
+
+		}
+		rmnet_shs_flush_table(rmnet_shs_cfg.ff_flag >= rmnet_shs_wq_fb_limit,
 				      RMNET_WQ_CTXT);
+
 		local_bh_enable();
 	}
 	SHS_TRACE_HIGH(RMNET_SHS_FLUSH,
 			     RMNET_SHS_FLUSH_DELAY_WQ_END,
-			     is_force_flush, 0xDEF, 0xDEF, 0xDEF, NULL, NULL);
+			     rmnet_shs_cfg.ff_flag, 0xDEF, 0xDEF, 0xDEF, NULL, NULL);
 }
 /* Invoked when the flushing timer has expired.
  * Upon first expiry, we set the flag that will trigger force flushing of all
@@ -1602,7 +1630,6 @@
 
 void rmnet_shs_dl_trl_handler(struct rmnet_map_dl_ind_trl *dltrl)
 {
-
 	SHS_TRACE_HIGH(RMNET_SHS_DL_MRK,
 			     RMNET_SHS_FLUSH_DL_MRK_TRLR_HDLR_START,
 			     rmnet_shs_cfg.num_pkts_parked, 0,
@@ -1740,12 +1767,14 @@
 	u8 is_shs_reqd = 0;
 	struct rmnet_shs_cpu_node_s *cpu_node_tbl_p;
 
+	rmnet_shs_in_count++;
+
 	/*deliver non TCP/UDP packets right away*/
 	if (!rmnet_shs_is_skb_stamping_reqd(skb)) {
+
 		rmnet_shs_deliver_skb(skb);
 		return;
 	}
-
 	if ((unlikely(!map)) || !rmnet_shs_cfg.rmnet_shs_init_complete) {
 		rmnet_shs_deliver_skb(skb);
 		SHS_TRACE_ERR(RMNET_SHS_ASSIGN,