• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Linux cfgp2p driver
3  *
4  * Copyright (C) 1999-2013, Broadcom Corporation
5  *
6  *      Unless you and Broadcom execute a separate written software license
7  * agreement governing use of this software, this software is licensed to you
8  * under the terms of the GNU General Public License version 2 (the "GPL"),
9  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
10  * following added to such license:
11  *
12  *      As a special exception, the copyright holders of this software give you
13  * permission to link this software with independent modules, and to copy and
14  * distribute the resulting executable under terms of your choice, provided that
15  * you also meet, for each linked independent module, the terms and conditions of
16  * the license of that module.  An independent module is a module which is not
17  * derived from this software.  The special exception does not apply to any
18  * modifications of the software.
19  *
20  *      Notwithstanding the above, under no circumstances may you combine this
21  * software in any way with any other Broadcom software provided under a license
22  * other than the GPL, without Broadcom's express prior written consent.
23  *
24  * $Id: wl_cfgp2p.h 415640 2013-07-31 02:43:28Z $
25  */
26 #ifndef _wl_cfgp2p_h_
27 #define _wl_cfgp2p_h_
28 #include <proto/802.11.h>
29 #include <proto/p2p.h>
30 
31 struct wl_priv;
32 extern u32 wl_dbg_level;
33 
34 typedef struct wifi_p2p_ie wifi_wfd_ie_t;
35 /* Enumeration of the usages of the BSSCFGs used by the P2P Library.  Do not
36  * confuse this with a bsscfg index.  This value is an index into the
37  * saved_ie[] array of structures which in turn contains a bsscfg index field.
38  */
39 typedef enum {
40 	P2PAPI_BSSCFG_PRIMARY, /* maps to driver's primary bsscfg */
41 	P2PAPI_BSSCFG_DEVICE, /* maps to driver's P2P device discovery bsscfg */
42 	P2PAPI_BSSCFG_CONNECTION, /* maps to driver's P2P connection bsscfg */
43 	P2PAPI_BSSCFG_MAX
44 } p2p_bsscfg_type_t;
45 
46 typedef enum {
47 	P2P_SCAN_PURPOSE_MIN,
48 	P2P_SCAN_SOCIAL_CHANNEL, /* scan for social channel */
49 	P2P_SCAN_AFX_PEER_NORMAL, /* scan for action frame search */
50 	P2P_SCAN_AFX_PEER_REDUCED, /* scan for action frame search with short time */
51 	P2P_SCAN_DURING_CONNECTED, /* scan during connected status */
52 	P2P_SCAN_CONNECT_TRY, /* scan for connecting */
53 	P2P_SCAN_NORMAL, /* scan during not-connected status */
54 	P2P_SCAN_PURPOSE_MAX
55 } p2p_scan_purpose_t;
56 
57 /* vendor ies max buffer length for probe response or beacon */
58 #define VNDR_IES_MAX_BUF_LEN	1400
59 /* normal vendor ies buffer length */
60 #define VNDR_IES_BUF_LEN 		512
61 
62 /* Structure to hold all saved P2P and WPS IEs for a BSSCFG */
63 struct p2p_saved_ie {
64 	u8  p2p_probe_req_ie[VNDR_IES_BUF_LEN];
65 	u8  p2p_probe_res_ie[VNDR_IES_MAX_BUF_LEN];
66 	u8  p2p_assoc_req_ie[VNDR_IES_BUF_LEN];
67 	u8  p2p_assoc_res_ie[VNDR_IES_BUF_LEN];
68 	u8  p2p_beacon_ie[VNDR_IES_MAX_BUF_LEN];
69 	u32 p2p_probe_req_ie_len;
70 	u32 p2p_probe_res_ie_len;
71 	u32 p2p_assoc_req_ie_len;
72 	u32 p2p_assoc_res_ie_len;
73 	u32 p2p_beacon_ie_len;
74 };
75 
76 struct p2p_bss {
77 	u32 bssidx;
78 	struct net_device *dev;
79 	struct p2p_saved_ie saved_ie;
80 	void *private_data;
81 };
82 
83 struct p2p_info {
84 	bool on;    /* p2p on/off switch */
85 	bool scan;
86 	int16 search_state;
87 	bool vif_created;
88 	s8 vir_ifname[IFNAMSIZ];
89 	unsigned long status;
90 	struct ether_addr dev_addr;
91 	struct ether_addr int_addr;
92 	struct p2p_bss bss[P2PAPI_BSSCFG_MAX];
93 	struct timer_list listen_timer;
94 	wl_p2p_sched_t noa;
95 	wl_p2p_ops_t ops;
96 	wlc_ssid_t ssid;
97 };
98 
99 #define MAX_VNDR_IE_NUMBER	5
100 
101 struct parsed_vndr_ie_info {
102 	char *ie_ptr;
103 	u32 ie_len;	/* total length including id & length field */
104 	vndr_ie_t vndrie;
105 };
106 
107 struct parsed_vndr_ies {
108 	u32 count;
109 	struct parsed_vndr_ie_info ie_info[MAX_VNDR_IE_NUMBER];
110 };
111 
112 /* dongle status */
113 enum wl_cfgp2p_status {
114 	WLP2P_STATUS_DISCOVERY_ON = 0,
115 	WLP2P_STATUS_SEARCH_ENABLED,
116 	WLP2P_STATUS_IF_ADD,
117 	WLP2P_STATUS_IF_DEL,
118 	WLP2P_STATUS_IF_DELETING,
119 	WLP2P_STATUS_IF_CHANGING,
120 	WLP2P_STATUS_IF_CHANGED,
121 	WLP2P_STATUS_LISTEN_EXPIRED,
122 	WLP2P_STATUS_ACTION_TX_COMPLETED,
123 	WLP2P_STATUS_ACTION_TX_NOACK,
124 	WLP2P_STATUS_SCANNING,
125 	WLP2P_STATUS_GO_NEG_PHASE,
126 	WLP2P_STATUS_DISC_IN_PROGRESS
127 };
128 
129 
130 #define wl_to_p2p_bss_ndev(wl, type)		((wl)->p2p->bss[type].dev)
131 #define wl_to_p2p_bss_bssidx(wl, type)		((wl)->p2p->bss[type].bssidx)
132 #define wl_to_p2p_bss_saved_ie(wl, type)	((wl)->p2p->bss[type].saved_ie)
133 #define wl_to_p2p_bss_private(wl, type)		((wl)->p2p->bss[type].private_data)
134 #define wl_to_p2p_bss(wl, type)			((wl)->p2p->bss[type])
135 #define wl_get_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0 : test_bit(WLP2P_STATUS_ ## stat, \
136 									&(wl)->p2p->status))
137 #define wl_set_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0 : set_bit(WLP2P_STATUS_ ## stat, \
138 									&(wl)->p2p->status))
139 #define wl_clr_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0 : clear_bit(WLP2P_STATUS_ ## stat, \
140 									&(wl)->p2p->status))
141 #define wl_chg_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0:change_bit(WLP2P_STATUS_ ## stat, \
142 									&(wl)->p2p->status))
143 #define p2p_on(wl) ((wl)->p2p->on)
144 #define p2p_scan(wl) ((wl)->p2p->scan)
145 #define p2p_is_on(wl) ((wl)->p2p && (wl)->p2p->on)
146 
147 /* dword align allocation */
148 #define WLC_IOCTL_MAXLEN 8192
149 
150 #define CFGP2P_ERROR_TEXT		"CFGP2P-ERROR) "
151 
152 
153 #define CFGP2P_ERR(args)									\
154 	do {										\
155 		if (wl_dbg_level & WL_DBG_ERR) {				\
156 			printk(KERN_INFO CFGP2P_ERROR_TEXT "%s : ", __func__);	\
157 			printk args;						\
158 		}									\
159 	} while (0)
160 #define	CFGP2P_INFO(args)									\
161 	do {										\
162 		if (wl_dbg_level & WL_DBG_INFO) {				\
163 			printk(KERN_INFO "CFGP2P-INFO) %s : ", __func__);	\
164 			printk args;						\
165 		}									\
166 	} while (0)
167 #define	CFGP2P_DBG(args)								\
168 	do {									\
169 		if (wl_dbg_level & WL_DBG_DBG) {			\
170 			printk(KERN_DEBUG "CFGP2P-DEBUG) %s :", __func__);	\
171 			printk args;							\
172 		}									\
173 	} while (0)
174 
175 #define	CFGP2P_ACTION(args)								\
176 	do {									\
177 		if (wl_dbg_level & WL_DBG_P2P_ACTION) {			\
178 			printk(KERN_DEBUG "CFGP2P-ACTION) %s :", __func__);	\
179 			printk args;							\
180 		}									\
181 	} while (0)
182 #define INIT_TIMER(timer, func, duration, extra_delay)	\
183 	do {				   \
184 		init_timer(timer); \
185 		timer->function = func; \
186 		timer->expires = jiffies + msecs_to_jiffies(duration + extra_delay); \
187 		timer->data = (unsigned long) wl; \
188 		add_timer(timer); \
189 	} while (0);
190 
191 #if !defined(WL_CFG80211_P2P_DEV_IF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
192 #define WL_CFG80211_P2P_DEV_IF
193 #endif /* !WL_CFG80211_P2P_DEV_IF && (LINUX_VERSION >= VERSION(3, 8, 0)) */
194 
195 #if defined(WL_ENABLE_P2P_IF) && (defined(WL_CFG80211_P2P_DEV_IF) || \
196 	(LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)))
197 #error Disable 'WL_ENABLE_P2P_IF', if 'WL_CFG80211_P2P_DEV_IF' is enabled \
198 	or kernel version is 3.8.0 or above
199 #endif /* WL_ENABLE_P2P_IF && (WL_CFG80211_P2P_DEV_IF || (LINUX_VERSION >= VERSION(3, 8, 0))) */
200 
201 #if !defined(WLP2P) && (defined(WL_ENABLE_P2P_IF) || defined(WL_CFG80211_P2P_DEV_IF))
202 #error WLP2P not defined
203 #endif
204 
205 #if defined(WL_CFG80211_P2P_DEV_IF)
206 #define bcm_struct_cfgdev	struct wireless_dev
207 #else
208 #define bcm_struct_cfgdev	struct net_device
209 #endif /* WL_CFG80211_P2P_DEV_IF */
210 
211 extern void
212 wl_cfgp2p_listen_expired(unsigned long data);
213 extern bool
214 wl_cfgp2p_is_pub_action(void *frame, u32 frame_len);
215 extern bool
216 wl_cfgp2p_is_p2p_action(void *frame, u32 frame_len);
217 extern bool
218 wl_cfgp2p_is_gas_action(void *frame, u32 frame_len);
219 extern bool
220 wl_cfgp2p_find_gas_subtype(u8 subtype, u8* data, u32 len);
221 extern void
222 wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len, u32 channel);
223 extern s32
224 wl_cfgp2p_init_priv(struct wl_priv *wl);
225 extern void
226 wl_cfgp2p_deinit_priv(struct wl_priv *wl);
227 extern s32
228 wl_cfgp2p_set_firm_p2p(struct wl_priv *wl);
229 extern s32
230 wl_cfgp2p_set_p2p_mode(struct wl_priv *wl, u8 mode,
231             u32 channel, u16 listen_ms, int bssidx);
232 extern s32
233 wl_cfgp2p_ifadd(struct wl_priv *wl, struct ether_addr *mac, u8 if_type,
234             chanspec_t chspec);
235 extern s32
236 wl_cfgp2p_ifdisable(struct wl_priv *wl, struct ether_addr *mac);
237 extern s32
238 wl_cfgp2p_ifdel(struct wl_priv *wl, struct ether_addr *mac);
239 extern s32
240 wl_cfgp2p_ifchange(struct wl_priv *wl, struct ether_addr *mac, u8 if_type, chanspec_t chspec);
241 
242 extern s32
243 wl_cfgp2p_ifidx(struct wl_priv *wl, struct ether_addr *mac, s32 *index);
244 
245 extern s32
246 wl_cfgp2p_init_discovery(struct wl_priv *wl);
247 extern s32
248 wl_cfgp2p_enable_discovery(struct wl_priv *wl, struct net_device *dev, const u8 *ie, u32 ie_len);
249 extern s32
250 wl_cfgp2p_disable_discovery(struct wl_priv *wl);
251 extern s32
252 wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active, u32 num_chans,
253 	u16 *channels,
254 	s32 search_state, u16 action, u32 bssidx, struct ether_addr *tx_dst_addr,
255 	p2p_scan_purpose_t p2p_scan_purpose);
256 
257 extern s32
258 wl_cfgp2p_act_frm_search(struct wl_priv *wl, struct net_device *ndev,
259 	s32 bssidx, s32 channel, struct ether_addr *tx_dst_addr);
260 
261 extern wpa_ie_fixed_t *
262 wl_cfgp2p_find_wpaie(u8 *parse, u32 len);
263 
264 extern wpa_ie_fixed_t *
265 wl_cfgp2p_find_wpsie(u8 *parse, u32 len);
266 
267 extern wifi_p2p_ie_t *
268 wl_cfgp2p_find_p2pie(u8 *parse, u32 len);
269 
270 extern wifi_wfd_ie_t *
271 wl_cfgp2p_find_wfdie(u8 *parse, u32 len);
272 extern s32
273 wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx,
274             s32 pktflag, const u8 *vndr_ie, u32 vndr_ie_len);
275 extern s32
276 wl_cfgp2p_clear_management_ie(struct wl_priv *wl, s32 bssidx);
277 
278 extern s32
279 wl_cfgp2p_find_idx(struct wl_priv *wl, struct net_device *ndev, s32 *index);
280 extern struct net_device *
281 wl_cfgp2p_find_ndev(struct wl_priv *wl, s32 bssidx);
282 extern s32
283 wl_cfgp2p_find_type(struct wl_priv *wl, s32 bssidx, s32 *type);
284 
285 
286 extern s32
287 wl_cfgp2p_listen_complete(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev,
288 	const wl_event_msg_t *e, void *data);
289 extern s32
290 wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms);
291 
292 extern s32
293 wl_cfgp2p_discover_enable_search(struct wl_priv *wl, u8 enable);
294 
295 extern s32
296 wl_cfgp2p_action_tx_complete(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev,
297 	const wl_event_msg_t *e, void *data);
298 
299 extern s32
300 wl_cfgp2p_tx_action_frame(struct wl_priv *wl, struct net_device *dev,
301 	wl_af_params_t *af_params, s32 bssidx);
302 
303 extern void
304 wl_cfgp2p_generate_bss_mac(struct ether_addr *primary_addr, struct ether_addr *out_dev_addr,
305             struct ether_addr *out_int_addr);
306 
307 extern void
308 wl_cfg80211_change_ifaddr(u8* buf, struct ether_addr *p2p_int_addr, u8 element_id);
309 extern bool
310 wl_cfgp2p_bss_isup(struct net_device *ndev, int bsscfg_idx);
311 
312 extern s32
313 wl_cfgp2p_bss(struct wl_priv *wl, struct net_device *ndev, s32 bsscfg_idx, s32 up);
314 
315 
316 extern s32
317 wl_cfgp2p_supported(struct wl_priv *wl, struct net_device *ndev);
318 
319 extern s32
320 wl_cfgp2p_down(struct wl_priv *wl);
321 
322 extern s32
323 wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int len);
324 
325 extern s32
326 wl_cfgp2p_get_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int len);
327 
328 extern s32
329 wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, struct net_device *ndev, char* buf, int len);
330 
331 extern u8 *
332 wl_cfgp2p_retreive_p2pattrib(void *buf, u8 element_id);
333 
334 extern u8*
335 wl_cfgp2p_find_attrib_in_all_p2p_Ies(u8 *parse, u32 len, u32 attrib);
336 
337 extern u8 *
338 wl_cfgp2p_retreive_p2p_dev_addr(wl_bss_info_t *bi, u32 bi_length);
339 
340 extern s32
341 wl_cfgp2p_register_ndev(struct wl_priv *wl);
342 
343 extern s32
344 wl_cfgp2p_unregister_ndev(struct wl_priv *wl);
345 
346 extern bool
347 wl_cfgp2p_is_ifops(const struct net_device_ops *if_ops);
348 
349 #if defined(WL_CFG80211_P2P_DEV_IF)
350 extern struct wireless_dev *
351 wl_cfgp2p_add_p2p_disc_if(void);
352 
353 extern int
354 wl_cfgp2p_start_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev);
355 
356 extern void
357 wl_cfgp2p_stop_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev);
358 
359 extern int
360 wl_cfgp2p_del_p2p_disc_if(struct wireless_dev *wdev);
361 #endif /* WL_CFG80211_P2P_DEV_IF */
362 
363 /* WiFi Direct */
364 #define SOCIAL_CHAN_1 1
365 #define SOCIAL_CHAN_2 6
366 #define SOCIAL_CHAN_3 11
367 #define IS_P2P_SOCIAL_CHANNEL(channel) ((channel == SOCIAL_CHAN_1) || \
368 					(channel == SOCIAL_CHAN_2) || \
369 					(channel == SOCIAL_CHAN_3))
370 #define SOCIAL_CHAN_CNT 3
371 #define AF_PEER_SEARCH_CNT 2
372 #define WL_P2P_WILDCARD_SSID "DIRECT-"
373 #define WL_P2P_WILDCARD_SSID_LEN 7
374 #define WL_P2P_INTERFACE_PREFIX "p2p"
375 #define WL_P2P_TEMP_CHAN 11
376 
377 /* If the provision discovery is for JOIN operations,
378  * or the device discoverablity frame is destined to GO
379  * then we need not do an internal scan to find GO.
380  */
381 #define IS_ACTPUB_WITHOUT_GROUP_ID(p2p_ie, len) \
382 	(wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_GROUP_ID) == NULL)
383 
384 #define IS_GAS_REQ(frame, len) (wl_cfgp2p_is_gas_action(frame, len) && \
385 					((frame->action == P2PSD_ACTION_ID_GAS_IREQ) || \
386 					(frame->action == P2PSD_ACTION_ID_GAS_CREQ)))
387 
388 #define IS_P2P_PUB_ACT_RSP_SUBTYPE(subtype) ((subtype == P2P_PAF_GON_RSP) || \
389 							((subtype == P2P_PAF_GON_CONF) || \
390 							(subtype == P2P_PAF_INVITE_RSP) || \
391 							(subtype == P2P_PAF_PROVDIS_RSP)))
392 #define IS_P2P_SOCIAL(ch) ((ch == SOCIAL_CHAN_1) || (ch == SOCIAL_CHAN_2) || (ch == SOCIAL_CHAN_3))
393 #define IS_P2P_SSID(ssid, len) (!memcmp(ssid, WL_P2P_WILDCARD_SSID, WL_P2P_WILDCARD_SSID_LEN) && \
394 					(len == WL_P2P_WILDCARD_SSID_LEN))
395 #endif				/* _wl_cfgp2p_h_ */
396