• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7 				* Redistributions of source code must retain the above copyright
8 						notice, this list of conditions and the following disclaimer.
9 				* Redistributions in binary form must reproduce the above
10 						copyright notice, this list of conditions and the following
11 						disclaimer in the documentation and/or other materials provided
12 						with the distribution.
13 				* Neither the name of The Linux Foundation nor the names of its
14 						contributors may be used to endorse or promote products derived
15 						from this software without specific prior written permission.
16 
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 /*!
30 		@file
31 		IPACM_Config.cpp
32 
33 		@brief
34 		This file implements the IPACM Configuration from XML file
35 
36 		@Author
37 		Skylar Chang
38 
39 */
40 #include <IPACM_Config.h>
41 #include <IPACM_Log.h>
42 #include <IPACM_Iface.h>
43 #include <sys/ioctl.h>
44 #include <fcntl.h>
45 
46 IPACM_Config *IPACM_Config::pInstance = NULL;
47 const char *IPACM_Config::DEVICE_NAME = "/dev/ipa";
48 const char *IPACM_Config::DEVICE_NAME_ODU = "/dev/odu_ipa_bridge";
49 
50 #define __stringify(x...) #x
51 
52 const char *ipacm_event_name[] = {
53 	__stringify(IPA_CFG_CHANGE_EVENT),                     /* NULL */
54 	__stringify(IPA_PRIVATE_SUBNET_CHANGE_EVENT),          /* ipacm_event_data_fid */
55 	__stringify(IPA_FIREWALL_CHANGE_EVENT),                /* NULL */
56 	__stringify(IPA_LINK_UP_EVENT),                        /* ipacm_event_data_fid */
57 	__stringify(IPA_LINK_DOWN_EVENT),                      /* ipacm_event_data_fid */
58 	__stringify(IPA_USB_LINK_UP_EVENT),                    /* ipacm_event_data_fid */
59 	__stringify(IPA_BRIDGE_LINK_UP_EVENT),                 /* ipacm_event_data_all */
60 	__stringify(IPA_WAN_EMBMS_LINK_UP_EVENT),              /* ipacm_event_data_mac */
61 	__stringify(IPA_ADDR_ADD_EVENT),                       /* ipacm_event_data_addr */
62 	__stringify(IPA_ADDR_DEL_EVENT),                       /* no use */
63 	__stringify(IPA_ROUTE_ADD_EVENT),                      /* ipacm_event_data_addr */
64 	__stringify(IPA_ROUTE_DEL_EVENT),                      /* ipacm_event_data_addr */
65 	__stringify(IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT),         /* ipacm_event_data_fid */
66 	__stringify(IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT),         /* ipacm_event_data_fid */
67 	__stringify(IPA_WLAN_AP_LINK_UP_EVENT),                /* ipacm_event_data_mac */
68 	__stringify(IPA_WLAN_STA_LINK_UP_EVENT),               /* ipacm_event_data_mac */
69 	__stringify(IPA_WLAN_LINK_DOWN_EVENT),                 /* ipacm_event_data_mac */
70 	__stringify(IPA_WLAN_CLIENT_ADD_EVENT),                /* ipacm_event_data_mac */
71 	__stringify(IPA_WLAN_CLIENT_ADD_EVENT_EX),             /* ipacm_event_data_wlan_ex */
72 	__stringify(IPA_WLAN_CLIENT_DEL_EVENT),                /* ipacm_event_data_mac */
73 	__stringify(IPA_WLAN_CLIENT_POWER_SAVE_EVENT),         /* ipacm_event_data_mac */
74 	__stringify(IPA_WLAN_CLIENT_RECOVER_EVENT),            /* ipacm_event_data_mac */
75 	__stringify(IPA_NEW_NEIGH_EVENT),                      /* ipacm_event_data_all */
76 	__stringify(IPA_DEL_NEIGH_EVENT),                      /* ipacm_event_data_all */
77 	__stringify(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT),       /* ipacm_event_data_all */
78 	__stringify(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT),       /* ipacm_event_data_all */
79 	__stringify(IPA_SW_ROUTING_ENABLE),                    /* NULL */
80 	__stringify(IPA_SW_ROUTING_DISABLE),                   /* NULL */
81 	__stringify(IPA_PROCESS_CT_MESSAGE),                   /* ipacm_ct_evt_data */
82 	__stringify(IPA_PROCESS_CT_MESSAGE_V6),                /* ipacm_ct_evt_data */
83 	__stringify(IPA_LAN_TO_LAN_NEW_CONNECTION),            /* ipacm_event_connection */
84 	__stringify(IPA_LAN_TO_LAN_DEL_CONNECTION),            /* ipacm_event_connection */
85 	__stringify(IPA_WLAN_SWITCH_TO_SCC),                   /* No Data */
86 	__stringify(IPA_WLAN_SWITCH_TO_MCC),                   /* No Data */
87 	__stringify(IPA_CRADLE_WAN_MODE_SWITCH),               /* ipacm_event_cradle_wan_mode */
88 	__stringify(IPA_WAN_XLAT_CONNECT_EVENT),               /* ipacm_event_data_fid */
89 	__stringify(IPA_TETHERING_STATS_UPDATE_EVENT),         /* ipacm_event_data_fid */
90 	__stringify(IPA_NETWORK_STATS_UPDATE_EVENT),           /* ipacm_event_data_fid */
91 	__stringify(IPA_DOWNSTREAM_ADD),                       /* ipacm_event_ipahal_stream */
92 	__stringify(IPA_DOWNSTREAM_DEL),                       /* ipacm_event_ipahal_stream */
93 	__stringify(IPA_EXTERNAL_EVENT_MAX),
94 	__stringify(IPA_HANDLE_WAN_UP),                        /* ipacm_event_iface_up  */
95 	__stringify(IPA_HANDLE_WAN_DOWN),                      /* ipacm_event_iface_up  */
96 	__stringify(IPA_HANDLE_WAN_UP_V6),                     /* NULL */
97 	__stringify(IPA_HANDLE_WAN_DOWN_V6),                   /* NULL */
98 	__stringify(IPA_HANDLE_WAN_UP_TETHER),                 /* ipacm_event_iface_up_tehter */
99 	__stringify(IPA_HANDLE_WAN_DOWN_TETHER),               /* ipacm_event_iface_up_tehter */
100 	__stringify(IPA_HANDLE_WAN_UP_V6_TETHER),              /* ipacm_event_iface_up_tehter */
101 	__stringify(IPA_HANDLE_WAN_DOWN_V6_TETHER),            /* ipacm_event_iface_up_tehter */
102 	__stringify(IPA_HANDLE_WLAN_UP),                       /* ipacm_event_iface_up */
103 	__stringify(IPA_HANDLE_LAN_UP),                        /* ipacm_event_iface_up */
104 	__stringify(IPA_ETH_BRIDGE_IFACE_UP),                  /* ipacm_event_eth_bridge*/
105 	__stringify(IPA_ETH_BRIDGE_IFACE_DOWN),                /* ipacm_event_eth_bridge*/
106 	__stringify(IPA_ETH_BRIDGE_CLIENT_ADD),                /* ipacm_event_eth_bridge*/
107 	__stringify(IPA_ETH_BRIDGE_CLIENT_DEL),                /* ipacm_event_eth_bridge*/
108 	__stringify(IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH),       /* ipacm_event_eth_bridge*/
109 	__stringify(IPA_SSR_NOTICE),                           /* NULL*/
110 	__stringify(IPA_COALESCE_NOTICE),                      /* NULL*/
111 #ifdef IPA_MTU_EVENT_MAX
112 	__stringify(IPA_MTU_SET),                              /* ipa_mtu_info */
113 	__stringify(IPA_MTU_UPDATE),                           /* ipacm_event_mtu_info */
114 #endif
115 #ifdef FEATURE_L2TP
116 	__stringify(IPA_ADD_VLAN_IFACE),                       /* ipa_ioc_vlan_iface_info */
117 	__stringify(IPA_DEL_VLAN_IFACE),                       /* ipa_ioc_vlan_iface_info */
118 	__stringify(IPA_ADD_L2TP_VLAN_MAPPING),                /* ipa_ioc_l2tp_vlan_mapping_info */
119 	__stringify(IPA_DEL_L2TP_VLAN_MAPPING),                /* ipa_ioc_l2tp_vlan_mapping_info */
120 	__stringify(IPA_VLAN_CLIENT_INFO),                     /* ipacm_event_data_all */
121 	__stringify(IPA_VLAN_IFACE_INFO),                      /* ipacm_event_data_all */
122 #endif
123 	__stringify(IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE),       /* ipacm_event_iface*/
124 	__stringify(IPA_LAN_DELETE_SELF),                      /* ipacm_event_data_fid */
125 	__stringify(IPA_WIGIG_CLIENT_ADD_EVENT),               /* ipacm_event_data_mac_ep */
126 	__stringify(IPA_WIGIG_FST_SWITCH),                     /* ipacm_event_data_fst */
127 	__stringify(IPACM_EVENT_MAX),
128 };
129 
IPACM_Config()130 IPACM_Config::IPACM_Config()
131 {
132 	iface_table = NULL;
133 	alg_table = NULL;
134 	pNatIfaces = NULL;
135 	memset(&ipa_client_rm_map_tbl, 0, sizeof(ipa_client_rm_map_tbl));
136 	memset(&ipa_rm_tbl, 0, sizeof(ipa_rm_tbl));
137 	ipa_rm_a2_check=0;
138 	ipacm_odu_enable = false;
139 	ipacm_odu_router_mode = false;
140 	ipa_num_wlan_guest_ap = 0;
141 
142 	ipa_num_ipa_interfaces = 0;
143 	ipa_num_private_subnet = 0;
144 	ipa_num_alg_ports = 0;
145 	ipa_nat_max_entries = 0;
146 	ipa_nat_iface_entries = 0;
147 	ipa_sw_rt_enable = false;
148 	ipa_bridge_enable = false;
149 	isMCC_Mode = false;
150 	ipa_max_valid_rm_entry = 0;
151 	/* IPA_HW_FNR_STATS */
152 	hw_fnr_stats_support = false;
153 	hw_counter_offset = 0;
154 	sw_counter_offset = 0;
155 
156 	memset(&rt_tbl_default_v4, 0, sizeof(rt_tbl_default_v4));
157 	memset(&rt_tbl_lan_v4, 0, sizeof(rt_tbl_lan_v4));
158 	memset(&rt_tbl_wan_v4, 0, sizeof(rt_tbl_wan_v4));
159 	memset(&rt_tbl_v6, 0, sizeof(rt_tbl_v6));
160 	memset(&rt_tbl_wan_v6, 0, sizeof(rt_tbl_wan_v6));
161 	memset(&rt_tbl_wan_dl, 0, sizeof(rt_tbl_wan_dl));
162 	memset(&rt_tbl_odu_v4, 0, sizeof(rt_tbl_odu_v4));
163 	memset(&rt_tbl_odu_v6, 0, sizeof(rt_tbl_odu_v6));
164 
165 	memset(&ext_prop_v4, 0, sizeof(ext_prop_v4));
166 	memset(&ext_prop_v6, 0, sizeof(ext_prop_v6));
167 
168 	qmap_id = ~0;
169 
170 	memset(flt_rule_count_v4, 0, IPA_CLIENT_MAX*sizeof(int));
171 	memset(flt_rule_count_v6, 0, IPA_CLIENT_MAX*sizeof(int));
172 	memset(bridge_mac, 0, IPA_MAC_ADDR_SIZE*sizeof(uint8_t));
173 
174 	IPACMDBG_H(" create IPACM_Config constructor\n");
175 	return;
176 }
177 
Init(void)178 int IPACM_Config::Init(void)
179 {
180 	/* Read IPACM Config file */
181 	char	IPACM_config_file[IPA_MAX_FILE_LEN];
182 	IPACM_conf_t	*cfg;
183 	cfg = (IPACM_conf_t *)malloc(sizeof(IPACM_conf_t));
184 	if(cfg == NULL)
185 	{
186 		IPACMERR("Unable to allocate cfg memory.\n");
187 		return IPACM_FAILURE;
188 	}
189 	uint32_t subnet_addr;
190 	uint32_t subnet_mask;
191 	int i, ret = IPACM_SUCCESS;
192 	struct in_addr in_addr_print;
193 
194 	m_fd = open(DEVICE_NAME, O_RDWR);
195 	if (0 > m_fd)
196 	{
197 		IPACMERR("Failed opening %s.\n", DEVICE_NAME);
198 	}
199 	ver = GetIPAVer(true);
200 #ifdef IPA_IOCTL_GET_HW_FEATURE_SUPPORT
201 	hw_feature = GetIPAFeatureSupport(true);
202 #endif
203 #ifdef FEATURE_IPACM_HAL
204 	strlcpy(IPACM_config_file, "/vendor/etc/IPACM_cfg.xml", sizeof(IPACM_config_file));
205 #else
206 	strlcpy(IPACM_config_file, "/etc/IPACM_cfg.xml", sizeof(IPACM_config_file));
207 #endif
208 	IPACMDBG_H("\n IPACM XML file is %s \n", IPACM_config_file);
209 	if (IPACM_SUCCESS == ipacm_read_cfg_xml(IPACM_config_file, cfg))
210 	{
211 		IPACMDBG_H("\n IPACM XML read OK \n");
212 	}
213 	else
214 	{
215 		IPACMERR("\n IPACM XML read failed \n");
216 		ret = IPACM_FAILURE;
217 		goto fail;
218 	}
219 
220 	/* Construct IPACM Iface table */
221 	ipa_num_ipa_interfaces = cfg->iface_config.num_iface_entries;
222 	if (iface_table != NULL)
223 	{
224 		free(iface_table);
225 		iface_table = NULL;
226 		IPACMDBG_H("RESET IPACM_Config::iface_table\n");
227 	}
228 	iface_table = (ipa_ifi_dev_name_t *)calloc(ipa_num_ipa_interfaces,
229 					sizeof(ipa_ifi_dev_name_t));
230 	if(iface_table == NULL)
231 	{
232 		IPACMERR("Unable to allocate iface_table memory.\n");
233 		ret = IPACM_FAILURE;
234 		goto fail;
235 	}
236 
237 	for (i = 0; i < cfg->iface_config.num_iface_entries; i++)
238 	{
239 		strlcpy(iface_table[i].iface_name, cfg->iface_config.iface_entries[i].iface_name, sizeof(iface_table[i].iface_name));
240 		iface_table[i].if_cat = cfg->iface_config.iface_entries[i].if_cat;
241 		iface_table[i].if_mode = cfg->iface_config.iface_entries[i].if_mode;
242 		iface_table[i].wlan_mode = cfg->iface_config.iface_entries[i].wlan_mode;
243 		IPACMDBG_H("IPACM_Config::iface_table[%d] = %s, cat=%d, mode=%d wlan-mode=%d \n", i, iface_table[i].iface_name,
244 				iface_table[i].if_cat, iface_table[i].if_mode, iface_table[i].wlan_mode);
245 		/* copy bridge interface name to ipacmcfg */
246 		if( iface_table[i].if_cat == VIRTUAL_IF)
247 		{
248 			strlcpy(ipa_virtual_iface_name, iface_table[i].iface_name, sizeof(ipa_virtual_iface_name));
249 			IPACMDBG_H("ipa_virtual_iface_name(%s) \n", ipa_virtual_iface_name);
250 		}
251 	}
252 
253 	/* Construct IPACM Private_Subnet table */
254 	memset(&private_subnet_table, 0, sizeof(private_subnet_table));
255 	ipa_num_private_subnet = cfg->private_subnet_config.num_subnet_entries;
256 
257 	for (i = 0; i < cfg->private_subnet_config.num_subnet_entries; i++)
258 	{
259 		memcpy(&private_subnet_table[i].subnet_addr,
260 					 &cfg->private_subnet_config.private_subnet_entries[i].subnet_addr,
261 					 sizeof(cfg->private_subnet_config.private_subnet_entries[i].subnet_addr));
262 
263 		memcpy(&private_subnet_table[i].subnet_mask,
264 					 &cfg->private_subnet_config.private_subnet_entries[i].subnet_mask,
265 					 sizeof(cfg->private_subnet_config.private_subnet_entries[i].subnet_mask));
266 
267 		subnet_addr = htonl(private_subnet_table[i].subnet_addr);
268 		memcpy(&in_addr_print,&subnet_addr,sizeof(in_addr_print));
269 		IPACMDBG_H("%dst::private_subnet_table= %s \n ", i,
270 						 inet_ntoa(in_addr_print));
271 
272 		subnet_mask =  htonl(private_subnet_table[i].subnet_mask);
273 		memcpy(&in_addr_print,&subnet_mask,sizeof(in_addr_print));
274 		IPACMDBG_H("%dst::private_subnet_table= %s \n ", i,
275 						 inet_ntoa(in_addr_print));
276 	}
277 
278 	/* Construct IPACM ALG table */
279 	ipa_num_alg_ports = cfg->alg_config.num_alg_entries;
280 	if (alg_table != NULL)
281 	{
282 		free(alg_table);
283 		alg_table = NULL;
284 		IPACMDBG_H("RESET IPACM_Config::alg_table \n");
285 	}
286 	alg_table = (ipacm_alg *)calloc(ipa_num_alg_ports,
287 				sizeof(ipacm_alg));
288 	if(alg_table == NULL)
289 	{
290 		IPACMERR("Unable to allocate alg_table memory.\n");
291 		ret = IPACM_FAILURE;
292 		free(iface_table);
293 		goto fail;;
294 	}
295 	for (i = 0; i < cfg->alg_config.num_alg_entries; i++)
296 	{
297 		alg_table[i].protocol = cfg->alg_config.alg_entries[i].protocol;
298 		alg_table[i].port = cfg->alg_config.alg_entries[i].port;
299 		IPACMDBG_H("IPACM_Config::ipacm_alg[%d] = %d, port=%d\n", i, alg_table[i].protocol, alg_table[i].port);
300 	}
301 
302 	ipa_nat_max_entries = cfg->nat_max_entries;
303 	IPACMDBG_H("Nat Maximum Entries %d\n", ipa_nat_max_entries);
304 
305 	/* Find ODU is either router mode or bridge mode*/
306 	ipacm_odu_enable = cfg->odu_enable;
307 	ipacm_odu_router_mode = cfg->router_mode_enable;
308 	ipacm_odu_embms_enable = cfg->odu_embms_enable;
309 	IPACMDBG_H("ipacm_odu_enable %d\n", ipacm_odu_enable);
310 	IPACMDBG_H("ipacm_odu_mode %d\n", ipacm_odu_router_mode);
311 	IPACMDBG_H("ipacm_odu_embms_enable %d\n", ipacm_odu_embms_enable);
312 
313 	ipacm_ip_passthrough_mode = cfg->ip_passthrough_mode;
314 	IPACMDBG_H("ipacm_ip_passthrough_mode %d. \n", ipacm_ip_passthrough_mode);
315 
316 	ipa_num_wlan_guest_ap = cfg->num_wlan_guest_ap;
317 	IPACMDBG_H("ipa_num_wlan_guest_ap %d\n",ipa_num_wlan_guest_ap);
318 
319 	/* Allocate more non-nat entries if the monitored iface dun have Tx/Rx properties */
320 	if (pNatIfaces != NULL)
321 	{
322 		free(pNatIfaces);
323 		pNatIfaces = NULL;
324 		IPACMDBG_H("RESET IPACM_Config::pNatIfaces \n");
325 	}
326 	ipa_nat_iface_entries = 0;
327 	pNatIfaces = (NatIfaces *)calloc(ipa_num_ipa_interfaces, sizeof(NatIfaces));
328 	if (pNatIfaces == NULL)
329 	{
330 		IPACMERR("unable to allocate nat ifaces\n");
331 		ret = IPACM_FAILURE;
332 		free(iface_table);
333 		free(alg_table);
334 		goto fail;
335 	}
336 
337 	/* Construct the routing table ictol name in iface static member*/
338 	rt_tbl_default_v4.ip = IPA_IP_v4;
339 	strlcpy(rt_tbl_default_v4.name, V4_DEFAULT_ROUTE_TABLE_NAME, sizeof(rt_tbl_default_v4.name));
340 
341 	rt_tbl_lan_v4.ip = IPA_IP_v4;
342 	strlcpy(rt_tbl_lan_v4.name, V4_LAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_lan_v4.name));
343 
344 	rt_tbl_wan_v4.ip = IPA_IP_v4;
345 	strlcpy(rt_tbl_wan_v4.name, V4_WAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_wan_v4.name));
346 
347 	rt_tbl_v6.ip = IPA_IP_v6;
348 	strlcpy(rt_tbl_v6.name, V6_COMMON_ROUTE_TABLE_NAME, sizeof(rt_tbl_v6.name));
349 
350 	rt_tbl_wan_v6.ip = IPA_IP_v6;
351 	strlcpy(rt_tbl_wan_v6.name, V6_WAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_wan_v6.name));
352 
353 	rt_tbl_odu_v4.ip = IPA_IP_v4;
354 	strlcpy(rt_tbl_odu_v4.name, V4_ODU_ROUTE_TABLE_NAME, sizeof(rt_tbl_odu_v4.name));
355 
356 	rt_tbl_odu_v6.ip = IPA_IP_v6;
357 	strlcpy(rt_tbl_odu_v6.name, V6_ODU_ROUTE_TABLE_NAME, sizeof(rt_tbl_odu_v6.name));
358 
359 	rt_tbl_wan_dl.ip = IPA_IP_MAX;
360 	strlcpy(rt_tbl_wan_dl.name, WAN_DL_ROUTE_TABLE_NAME, sizeof(rt_tbl_wan_dl.name));
361 
362 	/* Construct IPACM ipa_client map to rm_resource table */
363 	ipa_client_rm_map_tbl[IPA_CLIENT_WLAN1_PROD]= IPA_RM_RESOURCE_WLAN_PROD;
364 	ipa_client_rm_map_tbl[IPA_CLIENT_USB_PROD]= IPA_RM_RESOURCE_USB_PROD;
365 	ipa_client_rm_map_tbl[IPA_CLIENT_A5_WLAN_AMPDU_PROD]= IPA_RM_RESOURCE_HSIC_PROD;
366 	ipa_client_rm_map_tbl[IPA_CLIENT_A2_EMBEDDED_PROD]= IPA_RM_RESOURCE_Q6_PROD;
367 	ipa_client_rm_map_tbl[IPA_CLIENT_A2_TETHERED_PROD]= IPA_RM_RESOURCE_Q6_PROD;
368 	ipa_client_rm_map_tbl[IPA_CLIENT_APPS_LAN_WAN_PROD]= IPA_RM_RESOURCE_Q6_PROD;
369 	ipa_client_rm_map_tbl[IPA_CLIENT_WLAN1_CONS]= IPA_RM_RESOURCE_WLAN_CONS;
370 	ipa_client_rm_map_tbl[IPA_CLIENT_WLAN2_CONS]= IPA_RM_RESOURCE_WLAN_CONS;
371 	ipa_client_rm_map_tbl[IPA_CLIENT_WLAN3_CONS]= IPA_RM_RESOURCE_WLAN_CONS;
372 	ipa_client_rm_map_tbl[IPA_CLIENT_WLAN4_CONS]= IPA_RM_RESOURCE_WLAN_CONS;
373 	ipa_client_rm_map_tbl[IPA_CLIENT_USB_CONS]= IPA_RM_RESOURCE_USB_CONS;
374 	ipa_client_rm_map_tbl[IPA_CLIENT_A2_EMBEDDED_CONS]= IPA_RM_RESOURCE_Q6_CONS;
375 	ipa_client_rm_map_tbl[IPA_CLIENT_A2_TETHERED_CONS]= IPA_RM_RESOURCE_Q6_CONS;
376 	ipa_client_rm_map_tbl[IPA_CLIENT_APPS_WAN_CONS]= IPA_RM_RESOURCE_Q6_CONS;
377 	ipa_client_rm_map_tbl[IPA_CLIENT_ODU_PROD]= IPA_RM_RESOURCE_ODU_ADAPT_PROD;
378 	ipa_client_rm_map_tbl[IPA_CLIENT_ODU_EMB_CONS]= IPA_RM_RESOURCE_ODU_ADAPT_CONS;
379 	ipa_client_rm_map_tbl[IPA_CLIENT_ODU_TETH_CONS]= IPA_RM_RESOURCE_ODU_ADAPT_CONS;
380 
381 	/* Create the entries which IPACM wants to add dependencies on */
382 	ipa_rm_tbl[0].producer_rm1 = IPA_RM_RESOURCE_WLAN_PROD;
383 	ipa_rm_tbl[0].consumer_rm1 = IPA_RM_RESOURCE_Q6_CONS;
384 	ipa_rm_tbl[0].producer_rm2 = IPA_RM_RESOURCE_Q6_PROD;
385 	ipa_rm_tbl[0].consumer_rm2 = IPA_RM_RESOURCE_WLAN_CONS;
386 
387 	ipa_rm_tbl[1].producer_rm1 = IPA_RM_RESOURCE_USB_PROD;
388 	ipa_rm_tbl[1].consumer_rm1 = IPA_RM_RESOURCE_Q6_CONS;
389 	ipa_rm_tbl[1].producer_rm2 = IPA_RM_RESOURCE_Q6_PROD;
390 	ipa_rm_tbl[1].consumer_rm2 = IPA_RM_RESOURCE_USB_CONS;
391 
392 	ipa_rm_tbl[2].producer_rm1 = IPA_RM_RESOURCE_WLAN_PROD;
393 	ipa_rm_tbl[2].consumer_rm1 = IPA_RM_RESOURCE_USB_CONS;
394 	ipa_rm_tbl[2].producer_rm2 = IPA_RM_RESOURCE_USB_PROD;
395 	ipa_rm_tbl[2].consumer_rm2 = IPA_RM_RESOURCE_WLAN_CONS;
396 
397 	ipa_rm_tbl[3].producer_rm1 = IPA_RM_RESOURCE_ODU_ADAPT_PROD;
398 	ipa_rm_tbl[3].consumer_rm1 = IPA_RM_RESOURCE_Q6_CONS;
399 	ipa_rm_tbl[3].producer_rm2 = IPA_RM_RESOURCE_Q6_PROD;
400 	ipa_rm_tbl[3].consumer_rm2 = IPA_RM_RESOURCE_ODU_ADAPT_CONS;
401 
402 	ipa_rm_tbl[4].producer_rm1 = IPA_RM_RESOURCE_WLAN_PROD;
403 	ipa_rm_tbl[4].consumer_rm1 = IPA_RM_RESOURCE_ODU_ADAPT_CONS;
404 	ipa_rm_tbl[4].producer_rm2 = IPA_RM_RESOURCE_ODU_ADAPT_PROD;
405 	ipa_rm_tbl[4].consumer_rm2 = IPA_RM_RESOURCE_WLAN_CONS;
406 
407 	ipa_rm_tbl[5].producer_rm1 = IPA_RM_RESOURCE_ODU_ADAPT_PROD;
408 	ipa_rm_tbl[5].consumer_rm1 = IPA_RM_RESOURCE_USB_CONS;
409 	ipa_rm_tbl[5].producer_rm2 = IPA_RM_RESOURCE_USB_PROD;
410 	ipa_rm_tbl[5].consumer_rm2 = IPA_RM_RESOURCE_ODU_ADAPT_CONS;
411 	ipa_max_valid_rm_entry = 6; /* max is IPA_MAX_RM_ENTRY (6)*/
412 
413 	IPACMDBG_H(" depend MAP-0 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_WLAN_PROD, IPA_RM_RESOURCE_Q6_CONS);
414 	IPACMDBG_H(" depend MAP-1 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_USB_PROD, IPA_RM_RESOURCE_Q6_CONS);
415 	IPACMDBG_H(" depend MAP-2 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_WLAN_PROD, IPA_RM_RESOURCE_USB_CONS);
416 	IPACMDBG_H(" depend MAP-3 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_ODU_ADAPT_PROD, IPA_RM_RESOURCE_Q6_CONS);
417 	IPACMDBG_H(" depend MAP-4 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_WLAN_PROD, IPA_RM_RESOURCE_ODU_ADAPT_CONS);
418 	IPACMDBG_H(" depend MAP-5 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_ODU_ADAPT_PROD, IPA_RM_RESOURCE_USB_CONS);
419 
420 fail:
421 	if (cfg != NULL)
422 	{
423 		free(cfg);
424 		cfg = NULL;
425 	}
426 
427 	return ret;
428 }
429 
GetInstance()430 IPACM_Config* IPACM_Config::GetInstance()
431 {
432 	int res = IPACM_SUCCESS;
433 
434 	if (pInstance == NULL)
435 	{
436 		pInstance = new IPACM_Config();
437 
438 		res = pInstance->Init();
439 		if (res != IPACM_SUCCESS)
440 		{
441 			delete pInstance;
442 			IPACMERR("unable to initialize config instance\n");
443 			return NULL;
444 		}
445 	}
446 
447 	return pInstance;
448 }
449 
GetAlgPorts(int nPorts,ipacm_alg * pAlgPorts)450 int IPACM_Config::GetAlgPorts(int nPorts, ipacm_alg *pAlgPorts)
451 {
452 	if (nPorts <= 0 || pAlgPorts == NULL)
453 	{
454 		IPACMERR("Invalid input\n");
455 		return -1;
456 	}
457 
458 	for (int cnt = 0; cnt < nPorts; cnt++)
459 	{
460 		pAlgPorts[cnt].protocol = alg_table[cnt].protocol;
461 		pAlgPorts[cnt].port = alg_table[cnt].port;
462 	}
463 
464 	return 0;
465 }
466 
GetNatIfaces(int nIfaces,NatIfaces * pIfaces)467 int IPACM_Config::GetNatIfaces(int nIfaces, NatIfaces *pIfaces)
468 {
469 	if (nIfaces <= 0 || pIfaces == NULL)
470 	{
471 		IPACMERR("Invalid input\n");
472 		return -1;
473 	}
474 
475 	for (int cnt=0; cnt<nIfaces; cnt++)
476 	{
477 		memcpy(pIfaces[cnt].iface_name,
478 					 pNatIfaces[cnt].iface_name,
479 					 sizeof(pIfaces[cnt].iface_name));
480 	}
481 
482 	return 0;
483 }
484 
485 
AddNatIfaces(char * dev_name,ipa_ip_type ip_type)486 int IPACM_Config::AddNatIfaces(char *dev_name, ipa_ip_type ip_type)
487 {
488 	int i;
489 	/* Check if this iface already in NAT-iface*/
490 	for(i = 0; i < ipa_nat_iface_entries; i++)
491 	{
492 		if(strncmp(dev_name,
493 							 pNatIfaces[i].iface_name,
494 							 sizeof(pNatIfaces[i].iface_name)) == 0)
495 		{
496 			IPACMDBG_H("Interface (%s) is add to nat iface already\n", dev_name);
497 			if (ip_type == IPA_IP_v4) {
498 				pNatIfaces[i].v4_up = true;
499 				IPACMDBG_H("Change v4_up to (%d) \n", pNatIfaces[i].v4_up);
500 			}
501 			if (ip_type == IPA_IP_v6) {
502 				pNatIfaces[i].v6_up = true;
503 				IPACMDBG_H("Change v6_up to (%d) \n", pNatIfaces[i].v6_up);
504 			}
505 				return 0;
506 		}
507 	}
508 
509 	IPACMDBG_H("Add iface %s to NAT-ifaces, origin it has %d nat ifaces\n",
510 					          dev_name, ipa_nat_iface_entries);
511 	ipa_nat_iface_entries++;
512 
513 	if (ipa_nat_iface_entries < ipa_num_ipa_interfaces)
514 	{
515 		strlcpy(pNatIfaces[ipa_nat_iface_entries - 1].iface_name,
516 					 dev_name, IPA_IFACE_NAME_LEN);
517 
518 		IPACMDBG_H("Add Nat IfaceName: %s ,update nat-ifaces number: %d\n",
519 						 pNatIfaces[ipa_nat_iface_entries - 1].iface_name,
520 						 ipa_nat_iface_entries);
521 		if (ip_type == IPA_IP_v4) {
522 			pNatIfaces[ipa_nat_iface_entries - 1].v4_up = true;
523 			IPACMDBG_H("Change v4_up to (%d) \n", pNatIfaces[ipa_nat_iface_entries - 1].v4_up);
524 		}
525 		if (ip_type == IPA_IP_v6) {
526 			pNatIfaces[ipa_nat_iface_entries - 1].v6_up = true;
527 			IPACMDBG_H("Change v6_up to (%d) \n", pNatIfaces[ipa_nat_iface_entries - 1].v6_up);
528 		}
529 	}
530 	return 0;
531 }
532 
DelNatIfaces(char * dev_name)533 int IPACM_Config::DelNatIfaces(char *dev_name)
534 {
535 	int i = 0;
536 	IPACMDBG_H("Del iface %s from NAT-ifaces, origin it has %d nat ifaces\n",
537 					 dev_name, ipa_nat_iface_entries);
538 
539 	for (i = 0; i < ipa_nat_iface_entries; i++)
540 	{
541 		if (strcmp(dev_name, pNatIfaces[i].iface_name) == 0)
542 		{
543 			IPACMDBG_H("Found Nat IfaceName: %s with nat-ifaces number: %d\n",
544 							 pNatIfaces[i].iface_name, ipa_nat_iface_entries);
545 
546 			/* Reset the matched entry */
547 			memset(pNatIfaces[i].iface_name, 0, IPA_IFACE_NAME_LEN);
548 			pNatIfaces[i].v4_up = false;
549 			pNatIfaces[i].v6_up = false;
550 
551 			for (; i < ipa_nat_iface_entries - 1; i++)
552 			{
553 				memcpy(pNatIfaces[i].iface_name,
554 							 pNatIfaces[i + 1].iface_name, IPA_IFACE_NAME_LEN);
555 				pNatIfaces[i].v4_up = pNatIfaces[i + 1].v4_up;
556 				pNatIfaces[i].v6_up = pNatIfaces[i + 1].v6_up;
557 
558 				/* Reset the copied entry */
559 				memset(pNatIfaces[i + 1].iface_name, 0, IPA_IFACE_NAME_LEN);
560 				pNatIfaces[i + 1].v4_up = false;
561 				pNatIfaces[i + 1].v6_up = false;
562 			}
563 			ipa_nat_iface_entries--;
564 			IPACMDBG_H("Update nat-ifaces number: %d\n", ipa_nat_iface_entries);
565 			return 0;
566 		}
567 	}
568 
569 	IPACMDBG_H("Can't find Nat IfaceName: %s with total nat-ifaces number: %d\n",
570 					    dev_name, ipa_nat_iface_entries);
571 	return 0;
572 }
573 
CheckNatIfaces(const char * dev_name,ipa_ip_type ip_type)574 int IPACM_Config::CheckNatIfaces(const char *dev_name, ipa_ip_type ip_type)
575 {
576 	int i = 0;
577 	IPACMDBG_H("Check iface %s for ip-type %d from NAT-ifaces, currently it has %d nat ifaces\n",
578 					 dev_name, ip_type, ipa_nat_iface_entries);
579 
580 	for (i = 0; i < ipa_nat_iface_entries; i++)
581 	{
582 		if (strcmp(dev_name, pNatIfaces[i].iface_name) == 0)
583 		{
584 			IPACMDBG_H("Find Nat IfaceName: %s ,previous nat-ifaces number: %d, v4_up %d, v6_up %d \n",
585 							 pNatIfaces[i].iface_name, ipa_nat_iface_entries, pNatIfaces[i].v4_up, pNatIfaces[i].v6_up);
586 			if (ip_type == IPA_IP_v4 && pNatIfaces[i].v4_up == true)
587 			{
588 				IPACMDBG_H(" v4_up=%d\n", pNatIfaces[i].v4_up);
589 				return 0;
590 			}
591 			if (ip_type == IPA_IP_v6 && pNatIfaces[i].v6_up == true)
592 			{
593 				IPACMDBG_H(" v6_up=%d\n", pNatIfaces[i].v6_up);
594 			return 0;
595 		}
596 			return -1;
597 		}
598 	}
599 	IPACMDBG_H("Can't find Nat IfaceName: %s for ip_type %d up with total nat-ifaces number: %d\n",
600 					    dev_name, ip_type, ipa_nat_iface_entries);
601 	return -1;
602 }
603 
604 /* for IPACM resource manager dependency usage
605    add either Tx or Rx ipa_rm_resource_name and
606    also indicate that endpoint property if valid */
AddRmDepend(ipa_rm_resource_name rm1,bool rx_bypass_ipa)607 void IPACM_Config::AddRmDepend(ipa_rm_resource_name rm1,bool rx_bypass_ipa)
608 {
609 	int retval = 0;
610 	struct ipa_ioc_rm_dependency dep;
611 
612 	IPACMDBG_H(" Got rm add-depend index : %d \n", rm1);
613 	/* ipa_rm_a2_check: IPA_RM_RESOURCE_Q6_CONS*/
614 	if(rm1 == IPA_RM_RESOURCE_Q6_CONS)
615 	{
616 		ipa_rm_a2_check+=1;
617 		IPACMDBG_H("got %d times default RT routing from A2 \n", ipa_rm_a2_check);
618 	}
619 
620 	for(int i=0;i<ipa_max_valid_rm_entry;i++)
621 	{
622 		if(rm1 == ipa_rm_tbl[i].producer_rm1)
623 		{
624 			ipa_rm_tbl[i].producer1_up = true;
625 			/* entry1's producer actually dun have registered Rx-property */
626 			ipa_rm_tbl[i].rx_bypass_ipa = rx_bypass_ipa;
627 			IPACMDBG_H("Matched RM_table entry: %d's producer_rm1 with non_rx_prop: %d \n", i,ipa_rm_tbl[i].rx_bypass_ipa);
628 
629 			if(ipa_rm_tbl[i].consumer1_up == true && ipa_rm_tbl[i].rm_set == false)
630 			{
631 				IPACMDBG_H("SETUP RM_table entry %d's bi-direction dependency  \n", i);
632 				/* add bi-directional dependency*/
633 				if(ipa_rm_tbl[i].rx_bypass_ipa)
634 				{
635 					IPACMDBG_H("Skip ADD entry %d's dependency between WLAN-Pro: %d, Con: %d \n", i, ipa_rm_tbl[i].producer_rm1,ipa_rm_tbl[i].consumer_rm1);
636 				}
637 				else
638 				{
639 					memset(&dep, 0, sizeof(dep));
640 					dep.resource_name = ipa_rm_tbl[i].producer_rm1;
641 					dep.depends_on_name = ipa_rm_tbl[i].consumer_rm1;
642 					retval = ioctl(m_fd, IPA_IOC_RM_ADD_DEPENDENCY, &dep);
643 					IPACMDBG_H("ADD entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
644 					if (retval)
645 					{
646 						IPACMERR("Failed adding dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval);
647 					}
648 				}
649 				memset(&dep, 0, sizeof(dep));
650 				dep.resource_name = ipa_rm_tbl[i].producer_rm2;
651 				dep.depends_on_name = ipa_rm_tbl[i].consumer_rm2;
652 				retval = ioctl(m_fd, IPA_IOC_RM_ADD_DEPENDENCY, &dep);
653 				IPACMDBG_H("ADD entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
654 				if (retval)
655 				{
656 					IPACMERR("Failed adding dependecny for RM_table entry %d's bi-direction dependency (error:%d)  \n", i,retval);
657 				}
658 				ipa_rm_tbl[i].rm_set = true;
659 			}
660 			else
661 			{
662 				IPACMDBG_H("Not SETUP RM_table entry %d: prod_up:%d, cons_up:%d, rm_set: %d \n", i,ipa_rm_tbl[i].producer1_up, ipa_rm_tbl[i].consumer1_up, ipa_rm_tbl[i].rm_set);
663 			}
664 		}
665 
666 		if(rm1 == ipa_rm_tbl[i].consumer_rm1)
667 		{
668 			ipa_rm_tbl[i].consumer1_up = true;
669 			IPACMDBG_H("Matched RM_table entry: %d's consumer_rm1 \n", i);
670 
671 			if(ipa_rm_tbl[i].producer1_up == true && ipa_rm_tbl[i].rm_set == false)
672 			{
673 				IPACMDBG_H("SETUP RM_table entry %d's bi-direction dependency  \n", i);
674 				/* add bi-directional dependency*/
675 				if(ipa_rm_tbl[i].rx_bypass_ipa)
676 				{
677 					IPACMDBG_H("Skip ADD entry %d's dependency between WLAN-Pro: %d, Con: %d \n", i, ipa_rm_tbl[i].producer_rm1,ipa_rm_tbl[i].consumer_rm1);
678 				}
679 				else
680 				{
681 					memset(&dep, 0, sizeof(dep));
682 					dep.resource_name = ipa_rm_tbl[i].producer_rm1;
683 					dep.depends_on_name = ipa_rm_tbl[i].consumer_rm1;
684 					retval = ioctl(m_fd, IPA_IOC_RM_ADD_DEPENDENCY, &dep);
685 					IPACMDBG_H("ADD entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
686 					if (retval)
687 					{
688 						IPACMERR("Failed adding dependecny for RM_table entry %d's bi-direction dependency (error:%d)  \n", i,retval);
689 					}
690 				}
691 
692 				memset(&dep, 0, sizeof(dep));
693 				dep.resource_name = ipa_rm_tbl[i].producer_rm2;
694 				dep.depends_on_name = ipa_rm_tbl[i].consumer_rm2;
695 				retval = ioctl(m_fd, IPA_IOC_RM_ADD_DEPENDENCY, &dep);
696 				IPACMDBG_H("ADD entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
697 				if (retval)
698 				{
699 					IPACMERR("Failed adding dependecny for RM_table entry %d's bi-direction dependency (error:%d)  \n", i,retval);
700 				}
701 				ipa_rm_tbl[i].rm_set = true;
702 			}
703 			else
704 			{
705 				IPACMDBG_H("Not SETUP RM_table entry %d: prod_up:%d, cons_up:%d, rm_set: %d \n", i,ipa_rm_tbl[i].producer1_up, ipa_rm_tbl[i].consumer1_up, ipa_rm_tbl[i].rm_set);
706 			}
707 	   }
708    }
709    return ;
710 }
711 
712 /* for IPACM resource manager dependency usage
713    delete either Tx or Rx ipa_rm_resource_name */
714 
DelRmDepend(ipa_rm_resource_name rm1)715 void IPACM_Config::DelRmDepend(ipa_rm_resource_name rm1)
716 {
717 	int retval = 0;
718 	struct ipa_ioc_rm_dependency dep;
719 
720 	IPACMDBG_H(" Got rm del-depend index : %d \n", rm1);
721 	/* ipa_rm_a2_check: IPA_RM_RESOURCE_Q6_CONS*/
722 	if(rm1 == IPA_RM_RESOURCE_Q6_CONS)
723 	{
724 		ipa_rm_a2_check-=1;
725 		IPACMDBG_H("Left %d times default RT routing from A2 \n", ipa_rm_a2_check);
726 	}
727 
728 	for(int i=0;i<ipa_max_valid_rm_entry;i++)
729 	{
730 
731 		if(rm1 == ipa_rm_tbl[i].producer_rm1)
732 		{
733 			if(ipa_rm_tbl[i].rm_set == true)
734 			{
735 				IPACMDBG_H("Matched RM_table entry: %d's producer_rm1 and dependency is up \n", i);
736 				ipa_rm_tbl[i].rm_set = false;
737 
738 				/* delete bi-directional dependency*/
739 				if(ipa_rm_tbl[i].rx_bypass_ipa)
740 				{
741 					IPACMDBG_H("Skip DEL entry %d's dependency between WLAN-Pro: %d, Con: %d \n", i, ipa_rm_tbl[i].producer_rm1,ipa_rm_tbl[i].consumer_rm1);
742 				}
743 				else
744 				{
745 					memset(&dep, 0, sizeof(dep));
746 					dep.resource_name = ipa_rm_tbl[i].producer_rm1;
747 					dep.depends_on_name = ipa_rm_tbl[i].consumer_rm1;
748 					retval = ioctl(m_fd, IPA_IOC_RM_DEL_DEPENDENCY, &dep);
749 					IPACMDBG_H("Delete entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
750 					if (retval)
751 					{
752 						IPACMERR("Failed deleting dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval);
753 					}
754 				}
755 				memset(&dep, 0, sizeof(dep));
756 				dep.resource_name = ipa_rm_tbl[i].producer_rm2;
757 				dep.depends_on_name = ipa_rm_tbl[i].consumer_rm2;
758 				retval = ioctl(m_fd, IPA_IOC_RM_DEL_DEPENDENCY, &dep);
759 				IPACMDBG_H("Delete entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
760 				if (retval)
761 				{
762 					IPACMERR("Failed deleting dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval);
763 				}
764 			}
765 			ipa_rm_tbl[i].producer1_up = false;
766 			ipa_rm_tbl[i].rx_bypass_ipa = false;
767 		}
768 		if(rm1 == ipa_rm_tbl[i].consumer_rm1)
769 		{
770 			/* ipa_rm_a2_check: IPA_RM_RESOURCE_!6_CONS*/
771 			if(ipa_rm_tbl[i].consumer_rm1 == IPA_RM_RESOURCE_Q6_CONS && ipa_rm_a2_check == 1)
772 			{
773 				IPACMDBG_H(" still have %d default RT routing from A2 \n", ipa_rm_a2_check);
774 				continue;
775 			}
776 
777 			if(ipa_rm_tbl[i].rm_set == true)
778 			{
779 				IPACMDBG_H("Matched RM_table entry: %d's consumer_rm1 and dependency is up \n", i);
780 				ipa_rm_tbl[i].rm_set = false;
781 				/* delete bi-directional dependency*/
782 				if(ipa_rm_tbl[i].rx_bypass_ipa)
783 				{
784 					IPACMDBG_H("Skip DEL entry %d's dependency between WLAN-Pro: %d, Con: %d \n", i, ipa_rm_tbl[i].producer_rm1,ipa_rm_tbl[i].consumer_rm1);
785 				}
786 				else
787 				{
788 					memset(&dep, 0, sizeof(dep));
789 					dep.resource_name = ipa_rm_tbl[i].producer_rm1;
790 					dep.depends_on_name = ipa_rm_tbl[i].consumer_rm1;
791 					retval = ioctl(m_fd, IPA_IOC_RM_DEL_DEPENDENCY, &dep);
792 					IPACMDBG_H("Delete entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
793 					if (retval)
794 					{
795 						IPACMERR("Failed deleting dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval);
796 					}
797 				}
798 
799 				memset(&dep, 0, sizeof(dep));
800 				dep.resource_name = ipa_rm_tbl[i].producer_rm2;
801 				dep.depends_on_name = ipa_rm_tbl[i].consumer_rm2;
802 				retval = ioctl(m_fd, IPA_IOC_RM_DEL_DEPENDENCY, &dep);
803 				IPACMDBG_H("Delete entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
804 				if (retval)
805 				{
806 					IPACMERR("Failed deleting dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval);
807 				}
808 			}
809 			ipa_rm_tbl[i].consumer1_up = false;
810 		}
811 	}
812 	return ;
813 }
814 
SetExtProp(ipa_ioc_query_intf_ext_props * prop)815 int IPACM_Config::SetExtProp(ipa_ioc_query_intf_ext_props *prop)
816 {
817 	int i, num;
818 
819 	if(prop == NULL || prop->num_ext_props <= 0)
820 	{
821 		IPACMERR("There is no extended property!\n");
822 		return IPACM_FAILURE;
823 	}
824 
825 	num = prop->num_ext_props;
826 	for(i=0; i<num; i++)
827 	{
828 		if(prop->ext[i].ip == IPA_IP_v4)
829 		{
830 			if(ext_prop_v4.num_ext_props >= MAX_NUM_EXT_PROPS)
831 			{
832 				IPACMERR("IPv4 extended property table is full!\n");
833 				continue;
834 			}
835 			memcpy(&ext_prop_v4.prop[ext_prop_v4.num_ext_props], &prop->ext[i], sizeof(struct ipa_ioc_ext_intf_prop));
836 			ext_prop_v4.num_ext_props++;
837 		}
838 		else if(prop->ext[i].ip == IPA_IP_v6)
839 		{
840 			if(ext_prop_v6.num_ext_props >= MAX_NUM_EXT_PROPS)
841 			{
842 				IPACMERR("IPv6 extended property table is full!\n");
843 				continue;
844 			}
845 			memcpy(&ext_prop_v6.prop[ext_prop_v6.num_ext_props], &prop->ext[i], sizeof(struct ipa_ioc_ext_intf_prop));
846 			ext_prop_v6.num_ext_props++;
847 		}
848 		else
849 		{
850 			IPACMERR("The IP type is not expected!\n");
851 			return IPACM_FAILURE;
852 		}
853 	}
854 
855 	IPACMDBG_H("Set extended property succeeded.\n");
856 
857 	return IPACM_SUCCESS;
858 }
859 
GetExtProp(ipa_ip_type ip_type)860 ipacm_ext_prop* IPACM_Config::GetExtProp(ipa_ip_type ip_type)
861 {
862 	if(ip_type == IPA_IP_v4)
863 		return &ext_prop_v4;
864 	else if(ip_type == IPA_IP_v6)
865 		return &ext_prop_v6;
866 	else
867 	{
868 		IPACMERR("Failed to get extended property: the IP version is neither IPv4 nor IPv6!\n");
869 		return NULL;
870 	}
871 }
872 
DelExtProp(ipa_ip_type ip_type)873 int IPACM_Config::DelExtProp(ipa_ip_type ip_type)
874 {
875 	if(ip_type != IPA_IP_v6)
876 	{
877 		memset(&ext_prop_v4, 0, sizeof(ext_prop_v4));
878 	}
879 
880 	if(ip_type != IPA_IP_v4)
881 	{
882 		memset(&ext_prop_v6, 0, sizeof(ext_prop_v6));
883 	}
884 
885 	return IPACM_SUCCESS;
886 }
887 
getEventName(ipa_cm_event_id event_id)888 const char* IPACM_Config::getEventName(ipa_cm_event_id event_id)
889 {
890 	if(event_id >= sizeof(ipacm_event_name)/sizeof(ipacm_event_name[0]))
891 	{
892 		IPACMERR("Event name array is not consistent with event array!\n");
893 		return NULL;
894 	}
895 
896 	return ipacm_event_name[event_id];
897 }
898 
GetIPAVer(bool get)899 enum ipa_hw_type IPACM_Config::GetIPAVer(bool get)
900 {
901 	int ret;
902 
903 	if(!get)
904 		return ver;
905 
906 	ret = ioctl(m_fd, IPA_IOC_GET_HW_VERSION, &ver);
907 	if(ret != 0)
908 	{
909 		IPACMERR("Failed to get IPA version with error %d.\n", ret);
910 		ver = IPA_HW_None;
911 		return IPA_HW_None;
912 	}
913 	IPACMDBG_H("IPA version is %d.\n", ver);
914 	return ver;
915 }
916 
917 #ifdef IPA_IOCTL_GET_HW_FEATURE_SUPPORT
GetIPAFeatureSupport(bool get)918 int IPACM_Config::GetIPAFeatureSupport(bool get)
919 {
920 	int ret;
921 
922 	if(!get)
923 		return hw_feature;
924 
925 	ret = ioctl(m_fd, IPA_IOC_GET_HW_FEATURE_SUPPORT, &hw_feature);
926 	if(ret != 0)
927 	{
928 		IPACMERR("Failed to get IPA HW feature support %d.\n", ret);
929 		hw_feature = 0;
930 		return hw_feature;
931 	}
932 	IPACMDBG_H("IPA HW supported feature %d.\n", hw_feature);
933 	return hw_feature;
934 }
935 #endif
936 
isEthBridgingSupported()937 bool IPACM_Config::isEthBridgingSupported()
938 {
939 	enum ipa_hw_type hw_type;
940 
941 	hw_type = GetIPAVer();
942 #ifdef IPA_IOCTL_GET_HW_FEATURE_SUPPORT
943 	if (hw_type >= IPA_HW_v4_11) {
944 		return ((hw_feature & IPA_HW_ETH_BRIDGING_SUPPORT_BMSK) != 0);
945 	}
946 #endif
947 
948 #ifdef IPA_HW_v4_7
949 	return ((hw_type >= IPA_HW_v4_5) &&
950 		(hw_type != IPA_HW_v4_7));
951 #else
952 	return (hw_type >= IPA_HW_v4_5);
953 #endif
954 }
955 
isIPAv3Supported()956 bool IPACM_Config::isIPAv3Supported()
957 {
958 	enum ipa_hw_type hw_type;
959 
960 	hw_type = GetIPAVer();
961 
962 	return (hw_type >= IPA_HW_v3_0);
963 }
964