Merge f71934d3123837969e04fa199c6b089be67f4496 on remote branch

Change-Id: I4218eb0bc624e8c97963e872b3d760c0c0dd8806
diff --git a/ipacm/src/Android.mk b/ipacm/src/Android.mk
index 78753b4..95635c2 100644
--- a/ipacm/src/Android.mk
+++ b/ipacm/src/Android.mk
@@ -1,6 +1,7 @@
 BOARD_PLATFORM_LIST := msm8909
 BOARD_PLATFORM_LIST += msm8916
 BOARD_PLATFORM_LIST += msm8917
+BOARD_PLATFORM_LIST += qm215
 BOARD_IPAv3_LIST := msm8998
 BOARD_IPAv3_LIST += sdm845
 BOARD_IPAv3_LIST += sdm710
diff --git a/ipacm/src/IPACM_Filtering.cpp b/ipacm/src/IPACM_Filtering.cpp
index 623bad4..a65b769 100644
--- a/ipacm/src/IPACM_Filtering.cpp
+++ b/ipacm/src/IPACM_Filtering.cpp
@@ -477,9 +477,28 @@
 
 	if(flt_rule_tbl == NULL)
 	{
-		IPACMERR("Invalid add_offload_req\n");
+		if(mux_id ==0)
+		{
+			IPACMERR("Invalid add_offload_req muxd: (%d)\n", mux_id);
+			close(fd_wwan_ioctl);
+			return false;
+		}
+#ifdef QMI_IPA_MAX_FILTERS_EX2_V01
+		/* used for sending mux_id info to modem for UL sky*/
+		IPACMDBG_H("sending mux_id info (%d) to modem for UL\n", mux_id);
+		memset(&qmi_add_msg, 0, sizeof(qmi_add_msg));
+		qmi_add_msg.embedded_call_mux_id_valid = true;
+		qmi_add_msg.embedded_call_mux_id = mux_id;
+		ret = ioctl(fd_wwan_ioctl, WAN_IOC_ADD_OFFLOAD_CONNECTION, &qmi_add_msg);
+		if (ret != 0)
+		{
+			IPACMERR("Failed sending WAN_IOC_ADD_OFFLOAD_CONNECTION with ret %d\n ", ret);
+			close(fd_wwan_ioctl);
+			return false;
+		}
+#endif
 		close(fd_wwan_ioctl);
-		return false;
+		return true;
 	}
 	/* check Max offload connections */
 	if (total_num_offload_rules + flt_rule_tbl->num_rules > QMI_IPA_MAX_FILTERS_V01)
@@ -640,6 +659,10 @@
 			goto fail;
 		}
 	}
+	/* update total_num_offload_rules */
+	total_num_offload_rules -= flt_rule_tbl->num_hdls;
+	IPACMDBG_H("total_num_offload_rules %d \n", total_num_offload_rules);
+
 fail:
 	close(fd_wwan_ioctl);
 	return result;
diff --git a/ipacm/src/IPACM_OffloadManager.cpp b/ipacm/src/IPACM_OffloadManager.cpp
index 6accd70..0e6a53e 100644
--- a/ipacm/src/IPACM_OffloadManager.cpp
+++ b/ipacm/src/IPACM_OffloadManager.cpp
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
@@ -238,39 +238,44 @@
 		/* copy to the cache */
 		for(int i = 0; i < MAX_EVENT_CACHE ;i++)
 		{
-			if(event_cache[latest_cache_index].valid == false)
+			if (latest_cache_index >= 0)
 			{
-				//do the copy
-				event_cache[latest_cache_index].valid = true;
-				event_cache[latest_cache_index].event = IPA_DOWNSTREAM_ADD;
-				memcpy(event_cache[latest_cache_index].dev_name, downstream_name, sizeof(event_cache[latest_cache_index].dev_name));
-				memcpy(&event_cache[latest_cache_index].prefix_cache, &prefix, sizeof(event_cache[latest_cache_index].prefix_cache));
-				if (prefix.fam == V4) {
-					IPACMDBG_H("cache event(%d) subnet info v4Addr (%x) v4Mask (%x) dev(%s) on entry (%d)\n",
-						event_cache[latest_cache_index].event,
-						event_cache[latest_cache_index].prefix_cache.v4Addr,
-						event_cache[latest_cache_index].prefix_cache.v4Mask,
-						event_cache[latest_cache_index].dev_name,
-						latest_cache_index);
-				} else {
-					IPACMDBG_H("cache event (%d) v6Addr: %08x:%08x:%08x:%08x \n",
-						event_cache[latest_cache_index].event,
-						event_cache[latest_cache_index].prefix_cache.v6Addr[0],
-						event_cache[latest_cache_index].prefix_cache.v6Addr[1],
-						event_cache[latest_cache_index].prefix_cache.v6Addr[2],
-						event_cache[latest_cache_index].prefix_cache.v6Addr[3]);
-					IPACMDBG_H("subnet v6Mask: %08x:%08x:%08x:%08x dev(%s) on entry(%d), \n",
-						event_cache[latest_cache_index].prefix_cache.v6Mask[0],
-						event_cache[latest_cache_index].prefix_cache.v6Mask[1],
-						event_cache[latest_cache_index].prefix_cache.v6Mask[2],
-						event_cache[latest_cache_index].prefix_cache.v6Mask[3],
-						event_cache[latest_cache_index].dev_name,
-						latest_cache_index);
+				if(event_cache[latest_cache_index].valid == false)
+				{
+					//do the copy
+					event_cache[latest_cache_index].valid = true;
+					event_cache[latest_cache_index].event = IPA_DOWNSTREAM_ADD;
+					memcpy(event_cache[latest_cache_index].dev_name, downstream_name,
+						sizeof(event_cache[latest_cache_index].dev_name));
+					memcpy(&event_cache[latest_cache_index].prefix_cache, &prefix,
+						sizeof(event_cache[latest_cache_index].prefix_cache));
+					if (prefix.fam == V4) {
+						IPACMDBG_H("cache event(%d) subnet info v4Addr (%x) v4Mask (%x) dev(%s) on entry (%d)\n",
+							event_cache[latest_cache_index].event,
+							event_cache[latest_cache_index].prefix_cache.v4Addr,
+							event_cache[latest_cache_index].prefix_cache.v4Mask,
+							event_cache[latest_cache_index].dev_name,
+							latest_cache_index);
+					} else {
+						IPACMDBG_H("cache event (%d) v6Addr: %08x:%08x:%08x:%08x \n",
+							event_cache[latest_cache_index].event,
+							event_cache[latest_cache_index].prefix_cache.v6Addr[0],
+							event_cache[latest_cache_index].prefix_cache.v6Addr[1],
+							event_cache[latest_cache_index].prefix_cache.v6Addr[2],
+							event_cache[latest_cache_index].prefix_cache.v6Addr[3]);
+						IPACMDBG_H("subnet v6Mask: %08x:%08x:%08x:%08x dev(%s) on entry(%d), \n",
+							event_cache[latest_cache_index].prefix_cache.v6Mask[0],
+							event_cache[latest_cache_index].prefix_cache.v6Mask[1],
+							event_cache[latest_cache_index].prefix_cache.v6Mask[2],
+							event_cache[latest_cache_index].prefix_cache.v6Mask[3],
+							event_cache[latest_cache_index].dev_name,
+							latest_cache_index);
+					}
+					latest_cache_index = (latest_cache_index + 1)% MAX_EVENT_CACHE;
+					break;
 				}
 				latest_cache_index = (latest_cache_index + 1)% MAX_EVENT_CACHE;
-				break;
 			}
-			latest_cache_index = (latest_cache_index + 1)% MAX_EVENT_CACHE;
 			if(i == MAX_EVENT_CACHE - 1)
 			{
 				IPACMDBG_H(" run out of event cache (%d)\n", i);
@@ -413,37 +418,43 @@
 			/* copy to the cache */
 			for(int i = 0; i < MAX_EVENT_CACHE ;i++)
 			{
-				if(event_cache[latest_cache_index].valid == false)
+				if (latest_cache_index >= 0)
 				{
-					//do the copy
-					event_cache[latest_cache_index].valid = true;
-					event_cache[latest_cache_index].event = IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT;
-					memcpy(event_cache[latest_cache_index].dev_name, upstream_name, sizeof(event_cache[latest_cache_index].dev_name));
-					memcpy(&event_cache[latest_cache_index].prefix_cache, &gw_addr_v4, sizeof(event_cache[latest_cache_index].prefix_cache));
-					memcpy(&event_cache[latest_cache_index].prefix_cache_v6, &gw_addr_v6, sizeof(event_cache[latest_cache_index].prefix_cache_v6));
-					if (gw_addr_v4.fam == V4) {
-						IPACMDBG_H("cache event(%d) ipv4 gateway: (%x) dev(%s) on entry (%d)\n",
-							event_cache[latest_cache_index].event,
-							event_cache[latest_cache_index].prefix_cache.v4Addr,
-							event_cache[latest_cache_index].dev_name,
-							latest_cache_index);
-		}
+					if(event_cache[latest_cache_index].valid == false)
+					{
+						//do the copy
+						event_cache[latest_cache_index].valid = true;
+						event_cache[latest_cache_index].event = IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT;
+						memcpy(event_cache[latest_cache_index].dev_name, upstream_name,
+							sizeof(event_cache[latest_cache_index].dev_name));
+						memcpy(&event_cache[latest_cache_index].prefix_cache, &gw_addr_v4,
+							sizeof(event_cache[latest_cache_index].prefix_cache));
+						memcpy(&event_cache[latest_cache_index].prefix_cache_v6, &gw_addr_v6,
+							sizeof(event_cache[latest_cache_index].prefix_cache_v6));
+						if (gw_addr_v4.fam == V4) {
+							IPACMDBG_H("cache event(%d) ipv4 gateway: (%x) dev(%s) on entry (%d)\n",
+								event_cache[latest_cache_index].event,
+								event_cache[latest_cache_index].prefix_cache.v4Addr,
+								event_cache[latest_cache_index].dev_name,
+								latest_cache_index);
+						}
 
-					if (gw_addr_v6.fam == V6)
-		{
-						IPACMDBG_H("cache event (%d) ipv6 gateway: %08x:%08x:%08x:%08x dev(%s) on entry(%d)\n",
-							event_cache[latest_cache_index].event,
-							event_cache[latest_cache_index].prefix_cache_v6.v6Addr[0],
-							event_cache[latest_cache_index].prefix_cache_v6.v6Addr[1],
-							event_cache[latest_cache_index].prefix_cache_v6.v6Addr[2],
-							event_cache[latest_cache_index].prefix_cache_v6.v6Addr[3],
-							event_cache[latest_cache_index].dev_name,
-							latest_cache_index);
+						if (gw_addr_v6.fam == V6)
+						{
+							IPACMDBG_H("cache event (%d) ipv6 gateway: %08x:%08x:%08x:%08x dev(%s) on entry(%d)\n",
+								event_cache[latest_cache_index].event,
+								event_cache[latest_cache_index].prefix_cache_v6.v6Addr[0],
+								event_cache[latest_cache_index].prefix_cache_v6.v6Addr[1],
+								event_cache[latest_cache_index].prefix_cache_v6.v6Addr[2],
+								event_cache[latest_cache_index].prefix_cache_v6.v6Addr[3],
+								event_cache[latest_cache_index].dev_name,
+								latest_cache_index);
+						}
+						latest_cache_index = (latest_cache_index + 1)% MAX_EVENT_CACHE;
+						break;
 					}
 					latest_cache_index = (latest_cache_index + 1)% MAX_EVENT_CACHE;
-					break;
 				}
-				latest_cache_index = (latest_cache_index + 1)% MAX_EVENT_CACHE;
 				if(i == MAX_EVENT_CACHE - 1)
 				{
 					IPACMDBG_H(" run out of event cache (%d) \n", i);
diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp
index 1400696..fe15232 100644
--- a/ipacm/src/IPACM_Wan.cpp
+++ b/ipacm/src/IPACM_Wan.cpp
@@ -141,6 +141,31 @@
 
 	if(iface_query != NULL)
 	{
+		IPACMDBG_H("index:%d constructor: Tx properties:%d\n", iface_index, iface_query->num_tx_props);
+
+		if(is_sta_mode == Q6_WAN)
+		{
+			query_ext_prop();
+
+			if ((iface_query->num_ext_props == 1) && ((ext_prop != NULL) && ext_prop->ext[0].ip == IPA_IP_MAX))
+			{
+				/* only has one ext properties with IP_MAX type, will be the mhi-modem */
+				IPACMDBG_H("One extended property for iface %s, replace %d to Q6_MHI_WAN\n", dev_name, is_sta_mode);
+				m_is_sta_mode = Q6_MHI_WAN;
+			}
+			else
+			{
+				IPACMDBG_H("The new WAN interface is modem.\n");
+				m_is_sta_mode = is_sta_mode;
+				is_default_gateway = false;
+			}
+		}
+		else
+		{
+			m_is_sta_mode = is_sta_mode;
+			IPACMDBG_H("The new WAN interface is WLAN STA.\n");
+		}
+
 		wan_client_len = (sizeof(ipa_wan_client)) + (iface_query->num_tx_props * sizeof(wan_client_rt_hdl));
 		wan_client = (ipa_wan_client *)calloc(IPA_MAX_NUM_WAN_CLIENTS, wan_client_len);
 		if (wan_client == NULL)
@@ -148,31 +173,11 @@
 			IPACMERR("unable to allocate memory\n");
 			return;
 		}
-		IPACMDBG_H("index:%d constructor: Tx properties:%d\n", iface_index, iface_query->num_tx_props);
-	}
-
-
-	if(is_sta_mode == Q6_WAN)
-	{
-		query_ext_prop();
-
-		if ((iface_query->num_ext_props == 1) && (ext_prop->ext[0].ip = IPA_IP_MAX))
-		{
-			/* only has one ext properties with IP_MAX type, will be the mhi-modem */
-			IPACMDBG_H("One extended property for iface %s, replace %d to Q6_MHI_WAN\n", dev_name, is_sta_mode);
-			m_is_sta_mode = Q6_MHI_WAN;
-		}
-		else
-		{
-			IPACMDBG_H("The new WAN interface is modem.\n");
-			m_is_sta_mode = is_sta_mode;
-			is_default_gateway = false;
-		}
 	}
 	else
 	{
-		m_is_sta_mode = is_sta_mode;
-		IPACMDBG_H("The new WAN interface is WLAN STA.\n");
+		IPACMDBG_H("iface_query is empty.\n");
+		return;
 	}
 
 	m_fd_ipa = open(IPA_DEVICE_NAME, O_RDWR);
@@ -1626,6 +1631,12 @@
 			IPACM_Wan::backhaul_mode = m_is_sta_mode;		
 			IPACMDBG_H("Setting up QMAP ID %d.\n", ext_prop->ext[0].mux_id);
 			IPACM_Iface::ipacmcfg->SetQmapId(ext_prop->ext[0].mux_id);
+			/* sending mux-id info to PCIE-modem for UL */
+			if(false == m_filtering.AddOffloadFilteringRule(NULL, ext_prop->ext[0].mux_id))
+			{
+				IPACMERR("Failed to send mux id info to modem.\n");
+				return IPACM_FAILURE;
+			}
 		}
 		else
 		{