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_Wlan.h
32 
33 		@brief
34 		This file implements the WLAN iface functionality.
35 
36 		@Author
37 		Skylar Chang
38 
39 */
40 #ifndef IPACM_WLAN_H
41 #define IPACM_WLAN_H
42 
43 #include <stdio.h>
44 #include <IPACM_CmdQueue.h>
45 #include <linux/msm_ipa.h>
46 #include "IPACM_Routing.h"
47 #include "IPACM_Filtering.h"
48 #include "IPACM_Lan.h"
49 #include "IPACM_Iface.h"
50 #include "IPACM_Conntrack_NATApp.h"
51 
52 typedef struct _wlan_client_rt_hdl
53 {
54 	uint32_t wifi_rt_rule_hdl_v4;
55 	uint32_t wifi_rt_rule_hdl_v6[IPV6_NUM_ADDR];
56 	uint32_t wifi_rt_rule_hdl_v6_wan[IPV6_NUM_ADDR];
57 
58 }wlan_client_rt_hdl;
59 
60 typedef struct _ipa_wlan_client
61 {
62 	ipacm_event_data_wlan_ex* p_hdr_info;
63 	uint8_t mac[IPA_MAC_ADDR_SIZE];
64 	uint32_t v4_addr;
65 	uint32_t v6_addr[IPV6_NUM_ADDR][4];
66 	uint32_t hdr_hdl_v4;
67 	uint32_t hdr_hdl_v6;
68 	bool route_rule_set_v4;
69 	int route_rule_set_v6;
70 	bool ipv4_set;
71 	int ipv6_set;
72 	bool ipv4_header_set;
73 	bool ipv6_header_set;
74 	bool power_save_set;
75 	enum ipa_client_type wigig_ipa_client;
76 	/* used for pcie-modem */
77 	uint32_t v6_rt_rule_id[IPV6_NUM_ADDR];
78 	wlan_client_rt_hdl wifi_rt_hdl[0]; /* depends on number of tx properties */
79 }ipa_wlan_client;
80 
81 /* wlan iface */
82 class IPACM_Wlan : public IPACM_Lan
83 {
84 
85 public:
86 
87 	IPACM_Wlan(int iface_index);
88 	virtual ~IPACM_Wlan(void);
89 
90 	static int total_num_wifi_clients;
91 
92 	void event_callback(ipa_cm_event_id event, void *data);
93 
94 	bool is_guest_ap();
95 
96 private:
97 
98 	bool m_is_guest_ap;
99 
100 	/* handle wlan access mode switch in ethernet bridging*/
101 	void eth_bridge_handle_wlan_mode_switch();
102 
103 
104 	int wlan_client_len;
105 	ipa_wlan_client *wlan_client;
106 
107 	int header_name_count;
108 	uint32_t num_wifi_client;
109 
110 	int wlan_ap_index;
111 
112 	static int num_wlan_ap_iface;
113 
114 	NatApp *Nat_App;
115 
get_client_memptr(ipa_wlan_client * param,int cnt)116 	inline ipa_wlan_client* get_client_memptr(ipa_wlan_client *param, int cnt)
117 	{
118 	    char *ret = ((char *)param) + (wlan_client_len * cnt);
119 		return (ipa_wlan_client *)ret;
120 	}
121 
get_wlan_client_index(uint8_t * mac_addr)122 	inline int get_wlan_client_index(uint8_t *mac_addr)
123 	{
124 		int cnt;
125 		int num_wifi_client_tmp = num_wifi_client;
126 
127 		IPACMDBG_H("Passed MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
128 						 mac_addr[0], mac_addr[1], mac_addr[2],
129 						 mac_addr[3], mac_addr[4], mac_addr[5]);
130 
131 		for(cnt = 0; cnt < num_wifi_client_tmp; cnt++)
132 		{
133 			IPACMDBG_H("stored MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
134 							 get_client_memptr(wlan_client, cnt)->mac[0],
135 							 get_client_memptr(wlan_client, cnt)->mac[1],
136 							 get_client_memptr(wlan_client, cnt)->mac[2],
137 							 get_client_memptr(wlan_client, cnt)->mac[3],
138 							 get_client_memptr(wlan_client, cnt)->mac[4],
139 							 get_client_memptr(wlan_client, cnt)->mac[5]);
140 
141 			if(memcmp(get_client_memptr(wlan_client, cnt)->mac,
142 								mac_addr,
143 								sizeof(get_client_memptr(wlan_client, cnt)->mac)) == 0)
144 			{
145 				IPACMDBG_H("Matched client index: %d\n", cnt);
146 				return cnt;
147 			}
148 		}
149 
150 		return IPACM_INVALID_INDEX;
151 	}
152 
delete_default_qos_rtrules(int clt_indx,ipa_ip_type iptype)153 	inline int delete_default_qos_rtrules(int clt_indx, ipa_ip_type iptype)
154 	{
155 		uint32_t tx_index;
156 		uint32_t rt_hdl;
157 		int num_v6;
158 
159 		if(iptype == IPA_IP_v4)
160 		{
161 		     for(tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
162 		     {
163 		        if((tx_prop->tx[tx_index].ip == IPA_IP_v4) && (get_client_memptr(wlan_client, clt_indx)->route_rule_set_v4==true)) /* for ipv4 */
164 			{
165 				IPACMDBG_H("Delete client index %d ipv4 Qos rules for tx:%d \n",clt_indx,tx_index);
166 				rt_hdl = get_client_memptr(wlan_client, clt_indx)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4;
167 
168 				if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v4) == false)
169 				{
170 					return IPACM_FAILURE;
171 				}
172 			}
173 		     } /* end of for loop */
174 
175 		     /* clean the 4 Qos ipv4 RT rules for client:clt_indx */
176 		     if(get_client_memptr(wlan_client, clt_indx)->route_rule_set_v4==true) /* for ipv4 */
177 		     {
178 				get_client_memptr(wlan_client, clt_indx)->route_rule_set_v4 = false;
179 		     }
180 		}
181 
182 		if(iptype == IPA_IP_v6)
183 		{
184 		    for(tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
185 		    {
186 
187 				if((tx_prop->tx[tx_index].ip == IPA_IP_v6) && (get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6 != 0)) /* for ipv6 */
188 				{
189 					for(num_v6 =0;num_v6 < get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6;num_v6++)
190 					{
191 						/* send client-v6 delete to pcie modem only with global ipv6 with tx_index = 0 one time*/
192 						if(is_global_ipv6_addr(get_client_memptr(wlan_client, clt_indx)->v6_addr[num_v6]) && (IPACM_Wan::backhaul_mode == Q6_MHI_WAN)
193 							&& (get_client_memptr(wlan_client, clt_indx)->v6_rt_rule_id[num_v6] > 0))
194 						{
195 							IPACMDBG_H("Delete client index %d ipv6 RT-rules for %d-st ipv6 for rule-id:%d\n", clt_indx,num_v6,
196 								get_client_memptr(wlan_client, clt_indx)->v6_rt_rule_id[num_v6]);
197 							if (del_connection(clt_indx, num_v6))
198 							{
199 								IPACMERR("PCIE filter rule deletion failed! (%d-client) %d v6-entry\n",clt_indx, num_v6);
200 							}
201 						}
202 
203 						IPACMDBG_H("Delete client index %d ipv6 Qos rules for %d-st ipv6 for tx:%d\n", clt_indx,num_v6,tx_index);
204 						rt_hdl = get_client_memptr(wlan_client, clt_indx)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6[num_v6];
205 						if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false)
206 						{
207 							return IPACM_FAILURE;
208 						}
209 
210 						rt_hdl = get_client_memptr(wlan_client, clt_indx)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[num_v6];
211 						if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false)
212 						{
213 							return IPACM_FAILURE;
214 						}
215 					}
216 
217 				}
218 			} /* end of for loop */
219 
220 		    /* clean the 4 Qos ipv6 RT rules for client:clt_indx */
221 		    if(get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6 != 0) /* for ipv6 */
222 		    {
223 		                 get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6 = 0;
224                     }
225 		}
226 
227 		return IPACM_SUCCESS;
228 	}
229 
230 	int handle_wigig_client_add(ipacm_event_data_mac_ep *data);
231 
232 	/* for handle wifi client initial,copy all partial headers (tx property) */
233 	int handle_wlan_client_init_ex(ipacm_event_data_wlan_ex *data);
234 
235 	/*handle wifi client */
236 	int handle_wlan_client_ipaddr(ipacm_event_data_all *data);
237 
238 	/*handle wifi client routing rule*/
239 	int handle_wlan_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptype);
240 
241 	/*handle wifi client power-save mode*/
242 	int handle_wlan_client_pwrsave(uint8_t *mac_addr);
243 
244 	/*handle wifi client del mode*/
245 	int handle_wlan_client_down_evt(uint8_t *mac_addr);
246 
247 	/*handle wlan iface down event*/
248 	int handle_down_evt();
249 
250 	/*handle reset wifi-client rt-rules */
251 	int handle_wlan_client_reset_rt(ipa_ip_type iptype);
252 
253 	void handle_SCC_MCC_switch(ipa_ip_type);
254 
255 	/* for pcie modem */
256 	int add_connection(int client_index, int v6_num);
257 
258 	int del_connection(int client_index, int v6_num);
259 
260 #ifdef FEATURE_IPACM_RESTART
261 	/*query wlan-clients */
262 	int ipa_query_wlan_client();
263 #endif
264 
265 };
266 
267 
268 #endif /* IPACM_WLAN_H */
269