• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Linux cfgp2p driver
3  *
4  * Copyright (C) 1999-2017, 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  *
25  * <<Broadcom-WL-IPTag/Open:>>
26  *
27  * $Id: wl_cfgp2p.h 676811 2016-12-24 20:48:46Z $
28  */
29 #ifndef _wl_cfgp2p_h_
30 #define _wl_cfgp2p_h_
31 #include <802.11.h>
32 #include <p2p.h>
33 
34 struct bcm_cfg80211;
35 extern u32 wl_dbg_level;
36 
37 typedef struct wifi_p2p_ie wifi_wfd_ie_t;
38 /* Enumeration of the usages of the BSSCFGs used by the P2P Library.  Do not
39  * confuse this with a bsscfg index.  This value is an index into the
40  * saved_ie[] array of structures which in turn contains a bsscfg index field.
41  */
42 typedef enum {
43     P2PAPI_BSSCFG_PRIMARY, /**< maps to driver's primary bsscfg */
44     P2PAPI_BSSCFG_DEVICE, /**< maps to driver's P2P device discovery bsscfg */
45     P2PAPI_BSSCFG_CONNECTION1, /**< maps to driver's P2P connection bsscfg */
46     P2PAPI_BSSCFG_CONNECTION2,
47     P2PAPI_BSSCFG_MAX
48 } p2p_bsscfg_type_t;
49 
50 typedef enum {
51     P2P_SCAN_PURPOSE_MIN,
52     P2P_SCAN_SOCIAL_CHANNEL, /**< scan for social channel */
53     P2P_SCAN_AFX_PEER_NORMAL, /**< scan for action frame search */
54     P2P_SCAN_AFX_PEER_REDUCED, /**< scan for action frame search with short time */
55     P2P_SCAN_DURING_CONNECTED, /**< scan during connected status */
56     P2P_SCAN_CONNECT_TRY, /**< scan for connecting */
57     P2P_SCAN_NORMAL, /**< scan during not-connected status */
58     P2P_SCAN_PURPOSE_MAX
59 } p2p_scan_purpose_t;
60 
61 /** vendor ies max buffer length for probe response or beacon */
62 #define VNDR_IES_MAX_BUF_LEN    1400
63 /** normal vendor ies buffer length */
64 #define VNDR_IES_BUF_LEN         512
65 
66 struct p2p_bss {
67     s32 bssidx;
68     struct net_device *dev;
69     void *private_data;
70     struct ether_addr mac_addr;
71 };
72 
73 struct p2p_info {
74 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
75     struct bcm_cfg80211 *cfg;
76 #endif
77     bool on;    /**< p2p on/off switch */
78     bool scan;
79     int16 search_state;
80     s8 vir_ifname[IFNAMSIZ];
81     unsigned long status;
82     struct p2p_bss bss[P2PAPI_BSSCFG_MAX];
83     struct timer_list listen_timer;
84     wl_p2p_sched_t noa;
85     wl_p2p_ops_t ops;
86     wlc_ssid_t ssid;
87     s8 p2p_go_count;
88 };
89 
90 #define MAX_VNDR_IE_NUMBER    10
91 
92 struct parsed_vndr_ie_info {
93     char *ie_ptr;
94     u32 ie_len;    /**< total length including id & length field */
95     vndr_ie_t vndrie;
96 };
97 
98 struct parsed_vndr_ies {
99     u32 count;
100     struct parsed_vndr_ie_info ie_info[MAX_VNDR_IE_NUMBER];
101 };
102 
103 /* dongle status */
104 enum wl_cfgp2p_status {
105     WLP2P_STATUS_DISCOVERY_ON = 0,
106     WLP2P_STATUS_SEARCH_ENABLED,
107     WLP2P_STATUS_IF_ADDING,
108     WLP2P_STATUS_IF_DELETING,
109     WLP2P_STATUS_IF_CHANGING,
110     WLP2P_STATUS_IF_CHANGED,
111     WLP2P_STATUS_LISTEN_EXPIRED,
112     WLP2P_STATUS_ACTION_TX_COMPLETED,
113     WLP2P_STATUS_ACTION_TX_NOACK,
114     WLP2P_STATUS_SCANNING,
115     WLP2P_STATUS_GO_NEG_PHASE,
116     WLP2P_STATUS_DISC_IN_PROGRESS
117 };
118 
119 
120 #define wl_to_p2p_bss_ndev(cfg, type)        ((cfg)->p2p->bss[type].dev)
121 #define wl_to_p2p_bss_bssidx(cfg, type)        ((cfg)->p2p->bss[type].bssidx)
122 #define wl_to_p2p_bss_macaddr(cfg, type)     &((cfg)->p2p->bss[type].mac_addr)
123 #define wl_to_p2p_bss_saved_ie(cfg, type)    ((cfg)->p2p->bss[type].saved_ie)
124 #define wl_to_p2p_bss_private(cfg, type)        ((cfg)->p2p->bss[type].private_data)
125 #define wl_to_p2p_bss(cfg, type)            ((cfg)->p2p->bss[type])
126 #define wl_get_p2p_status(cfg, stat) ((!(cfg)->p2p_supported) ? 0 : \
127         test_bit(WLP2P_STATUS_ ## stat, &(cfg)->p2p->status))
128 #define wl_set_p2p_status(cfg, stat) ((!(cfg)->p2p_supported) ? 0 : \
129         set_bit(WLP2P_STATUS_ ## stat, &(cfg)->p2p->status))
130 #define wl_clr_p2p_status(cfg, stat) ((!(cfg)->p2p_supported) ? 0 : \
131         clear_bit(WLP2P_STATUS_ ## stat, &(cfg)->p2p->status))
132 #define wl_chg_p2p_status(cfg, stat) ((!(cfg)->p2p_supported) ? 0 : \
133     change_bit(WLP2P_STATUS_ ## stat, &(cfg)->p2p->status))
134 #define p2p_on(cfg) ((cfg)->p2p->on)
135 #define p2p_scan(cfg) ((cfg)->p2p->scan)
136 #define p2p_is_on(cfg) ((cfg)->p2p && (cfg)->p2p->on)
137 
138 /* dword align allocation */
139 #define WLC_IOCTL_MAXLEN 8192
140 
141 #ifdef CUSTOMER_HW4_DEBUG
142 #define CFGP2P_ERROR_TEXT        "CFGP2P-INFO2) "
143 #else
144 #define CFGP2P_ERROR_TEXT        "CFGP2P-ERROR) "
145 #endif /* CUSTOMER_HW4_DEBUG */
146 
147 #ifdef DHD_LOG_DUMP
148 #define CFGP2P_ERR(args)                                    \
149     do {                                        \
150         if (wl_dbg_level & WL_DBG_ERR) {                \
151             printk(KERN_INFO CFGP2P_ERROR_TEXT "%s : ", __func__);    \
152             printk args;                        \
153             DHD_LOG_DUMP_WRITE("[%s] %s: ",    \
154             dhd_log_dump_get_timestamp(), __func__);    \
155             DHD_LOG_DUMP_WRITE args;    \
156         }                                    \
157     } while (0)
158 #else
159 #define CFGP2P_ERR(args)                                    \
160     do {                                        \
161         if (wl_dbg_level & WL_DBG_ERR) {                \
162             printk(KERN_INFO CFGP2P_ERROR_TEXT "%s : ", __func__);    \
163             printk args;                        \
164         }                                    \
165     } while (0)
166 #endif /* DHD_LOG_DUMP */
167 #define    CFGP2P_INFO(args)                                    \
168     do {                                        \
169         if (wl_dbg_level & WL_DBG_INFO) {                \
170             printk(KERN_INFO "CFGP2P-INFO) %s : ", __func__);    \
171             printk args;                        \
172         }                                    \
173     } while (0)
174 #define    CFGP2P_DBG(args)                                \
175     do {                                    \
176         if (wl_dbg_level & WL_DBG_DBG) {            \
177             printk(KERN_INFO "CFGP2P-DEBUG) %s :", __func__);    \
178             printk args;                            \
179         }                                    \
180     } while (0)
181 
182 #define    CFGP2P_ACTION(args)                                \
183     do {                                    \
184         if (wl_dbg_level & WL_DBG_P2P_ACTION) {            \
185             printk(KERN_INFO "CFGP2P-ACTION) %s :", __func__);    \
186             printk args;                            \
187         }                                    \
188     } while (0)
189 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
190 #define INIT_TIMER(timer, func, duration, extra_delay)    \
191     do {                   \
192         timer_setup(timer, func, 0); \
193         timer->expires = jiffies + msecs_to_jiffies(duration + extra_delay); \
194         add_timer(timer); \
195     } while (0);
196 #else
197 #define INIT_TIMER(timer, func, duration, extra_delay)    \
198     do {                   \
199         init_timer(timer); \
200         timer->function = func; \
201         timer->expires = jiffies + msecs_to_jiffies(duration + extra_delay); \
202         timer->data = (unsigned long) cfg; \
203         add_timer(timer); \
204     } while (0);
205 #endif
206 
207 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 0, 8))
208 #ifdef WL_SUPPORT_BACKPORTED_KPATCHES
209 #undef WL_SUPPORT_BACKPORTED_KPATCHES
210 #endif
211 #endif
212 
213 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
214 #ifdef WL_CFG80211_STA_EVENT
215 #undef WL_CFG80211_STA_EVENT
216 #endif
217 #endif
218 
219 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) && !defined(WL_CFG80211_P2P_DEV_IF)
220 #define WL_CFG80211_P2P_DEV_IF
221 
222 #ifdef WL_ENABLE_P2P_IF
223 #undef WL_ENABLE_P2P_IF
224 #endif
225 
226 #ifdef WL_SUPPORT_BACKPORTED_KPATCHES
227 #undef WL_SUPPORT_BACKPORTED_KPATCHES
228 #endif
229 #else
230 #ifdef WLP2P
231 #ifndef WL_ENABLE_P2P_IF
232 /* Enable P2P network Interface if P2P support is enabled */
233 #define WL_ENABLE_P2P_IF
234 #endif /* WL_ENABLE_P2P_IF */
235 #endif /* WLP2P */
236 #endif /* (LINUX_VERSION >= VERSION(3, 8, 0)) */
237 
238 #ifndef WL_CFG80211_P2P_DEV_IF
239 #endif /* WL_CFG80211_P2P_DEV_IF */
240 
241 #if defined(WL_ENABLE_P2P_IF) && (defined(WL_CFG80211_P2P_DEV_IF) || \
242     (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)))
243 #error Disable 'WL_ENABLE_P2P_IF', if 'WL_CFG80211_P2P_DEV_IF' is enabled \
244     or kernel version is 3.8.0 or above
245 #endif /* WL_ENABLE_P2P_IF && (WL_CFG80211_P2P_DEV_IF || (LINUX_VERSION >= VERSION(3, 8, 0))) */
246 
247 #if !defined(WLP2P) && (defined(WL_ENABLE_P2P_IF) || defined(WL_CFG80211_P2P_DEV_IF))
248 #error WLP2P not defined
249 #endif /* !WLP2P && (WL_ENABLE_P2P_IF || WL_CFG80211_P2P_DEV_IF) */
250 
251 #if defined(WL_CFG80211_P2P_DEV_IF)
252 #define bcm_struct_cfgdev    struct wireless_dev
253 #else
254 #define bcm_struct_cfgdev    struct net_device
255 #endif /* WL_CFG80211_P2P_DEV_IF */
256 
257 #define P2P_ECSA_CNT 50
258 
259 extern void
260 wl_cfgp2p_listen_expired(
261 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
262     struct timer_list *t
263 #else
264     ulong data
265 #endif
266 );
267 extern bool
268 wl_cfgp2p_is_pub_action(void *frame, u32 frame_len);
269 extern bool
270 wl_cfgp2p_is_p2p_action(void *frame, u32 frame_len);
271 extern bool
272 wl_cfgp2p_is_gas_action(void *frame, u32 frame_len);
273 extern bool
274 wl_cfgp2p_find_gas_subtype(u8 subtype, u8* data, u32 len);
275 extern bool
276 wl_cfgp2p_is_p2p_gas_action(void *frame, u32 frame_len);
277 extern void
278 wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len, u32 channel);
279 extern s32
280 wl_cfgp2p_init_priv(struct bcm_cfg80211 *cfg);
281 extern void
282 wl_cfgp2p_deinit_priv(struct bcm_cfg80211 *cfg);
283 extern s32
284 wl_cfgp2p_set_firm_p2p(struct bcm_cfg80211 *cfg);
285 extern s32
286 wl_cfgp2p_set_p2p_mode(struct bcm_cfg80211 *cfg, u8 mode,
287             u32 channel, u16 listen_ms, int bssidx);
288 extern s32
289 wl_cfgp2p_ifadd(struct bcm_cfg80211 *cfg, struct ether_addr *mac, u8 if_type,
290             chanspec_t chspec);
291 extern s32
292 wl_cfgp2p_ifdisable(struct bcm_cfg80211 *cfg, struct ether_addr *mac);
293 extern s32
294 wl_cfgp2p_ifdel(struct bcm_cfg80211 *cfg, struct ether_addr *mac);
295 extern s32
296 wl_cfgp2p_ifchange(struct bcm_cfg80211 *cfg, struct ether_addr *mac, u8 if_type,
297     chanspec_t chspec, s32 conn_idx);
298 
299 extern s32
300 wl_cfgp2p_ifidx(struct bcm_cfg80211 *cfg, struct ether_addr *mac, s32 *index);
301 
302 extern s32
303 wl_cfgp2p_init_discovery(struct bcm_cfg80211 *cfg);
304 extern s32
305 wl_cfgp2p_enable_discovery(struct bcm_cfg80211 *cfg, struct net_device *dev, const u8 *ie,
306     u32 ie_len);
307 extern s32
308 wl_cfgp2p_disable_discovery(struct bcm_cfg80211 *cfg);
309 extern s32
310 wl_cfgp2p_escan(struct bcm_cfg80211 *cfg, struct net_device *dev, u16 active, u32 num_chans,
311     u16 *channels,
312     s32 search_state, u16 action, u32 bssidx, struct ether_addr *tx_dst_addr,
313     p2p_scan_purpose_t p2p_scan_purpose);
314 
315 extern s32
316 wl_cfgp2p_act_frm_search(struct bcm_cfg80211 *cfg, struct net_device *ndev,
317     s32 bssidx, s32 channel, struct ether_addr *tx_dst_addr);
318 
319 extern wpa_ie_fixed_t *
320 wl_cfgp2p_find_wpaie(u8 *parse, u32 len);
321 
322 extern wpa_ie_fixed_t *
323 wl_cfgp2p_find_wpsie(u8 *parse, u32 len);
324 
325 extern wifi_p2p_ie_t *
326 wl_cfgp2p_find_p2pie(u8 *parse, u32 len);
327 
328 extern wifi_wfd_ie_t *
329 wl_cfgp2p_find_wfdie(u8 *parse, u32 len);
330 extern s32
331 wl_cfgp2p_set_management_ie(struct bcm_cfg80211 *cfg, struct net_device *ndev, s32 bssidx,
332             s32 pktflag, const u8 *vndr_ie, u32 vndr_ie_len);
333 extern s32
334 wl_cfgp2p_clear_management_ie(struct bcm_cfg80211 *cfg, s32 bssidx);
335 
336 extern struct net_device *
337 wl_cfgp2p_find_ndev(struct bcm_cfg80211 *cfg, s32 bssidx);
338 extern s32
339 wl_cfgp2p_find_type(struct bcm_cfg80211 *cfg, s32 bssidx, s32 *type);
340 
341 
342 extern s32
343 wl_cfgp2p_listen_complete(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
344     const wl_event_msg_t *e, void *data);
345 extern s32
346 wl_cfgp2p_discover_listen(struct bcm_cfg80211 *cfg, s32 channel, u32 duration_ms);
347 
348 extern s32
349 wl_cfgp2p_discover_enable_search(struct bcm_cfg80211 *cfg, u8 enable);
350 
351 extern s32
352 wl_cfgp2p_action_tx_complete(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
353     const wl_event_msg_t *e, void *data);
354 
355 extern s32
356 wl_cfgp2p_tx_action_frame(struct bcm_cfg80211 *cfg, struct net_device *dev,
357     wl_af_params_t *af_params, s32 bssidx);
358 
359 extern void
360 wl_cfgp2p_generate_bss_mac(struct bcm_cfg80211 *cfg, struct ether_addr *primary_addr);
361 
362 extern void
363 wl_cfg80211_change_ifaddr(u8* buf, struct ether_addr *p2p_int_addr, u8 element_id);
364 
365 extern s32
366 wl_cfgp2p_supported(struct bcm_cfg80211 *cfg, struct net_device *ndev);
367 
368 extern s32
369 wl_cfgp2p_down(struct bcm_cfg80211 *cfg);
370 
371 extern s32
372 wl_cfgp2p_set_p2p_noa(struct bcm_cfg80211 *cfg, struct net_device *ndev, char* buf, int len);
373 
374 extern s32
375 wl_cfgp2p_get_p2p_noa(struct bcm_cfg80211 *cfg, struct net_device *ndev, char* buf, int len);
376 
377 extern s32
378 wl_cfgp2p_set_p2p_ps(struct bcm_cfg80211 *cfg, struct net_device *ndev, char* buf, int len);
379 
380 extern s32
381 wl_cfgp2p_set_p2p_ecsa(struct bcm_cfg80211 *cfg, struct net_device *ndev, char* buf, int len);
382 
383 extern s32
384 wl_cfgp2p_increase_p2p_bw(struct bcm_cfg80211 *cfg, struct net_device *ndev, char* buf, int len);
385 
386 extern u8 *
387 wl_cfgp2p_retreive_p2pattrib(void *buf, u8 element_id);
388 
389 extern u8*
390 wl_cfgp2p_find_attrib_in_all_p2p_Ies(u8 *parse, u32 len, u32 attrib);
391 
392 extern u8 *
393 wl_cfgp2p_retreive_p2p_dev_addr(wl_bss_info_t *bi, u32 bi_length);
394 
395 extern s32
396 wl_cfgp2p_register_ndev(struct bcm_cfg80211 *cfg);
397 
398 extern s32
399 wl_cfgp2p_unregister_ndev(struct bcm_cfg80211 *cfg);
400 
401 extern bool
402 wl_cfgp2p_is_ifops(const struct net_device_ops *if_ops);
403 
404 extern u32
405 wl_cfgp2p_vndr_ie(struct bcm_cfg80211 *cfg, u8 *iebuf, s32 pktflag,
406     s8 *oui, s32 ie_id, s8 *data, s32 datalen, const s8* add_del_cmd);
407 
408 extern int wl_cfgp2p_get_conn_idx(struct bcm_cfg80211 *cfg);
409 
410 extern
411 int wl_cfg_multip2p_operational(struct bcm_cfg80211 *cfg);
412 
413 extern
414 int wl_cfgp2p_vif_created(struct bcm_cfg80211 *cfg);
415 
416 #if defined(WL_CFG80211_P2P_DEV_IF)
417 extern struct wireless_dev *
418 wl_cfgp2p_add_p2p_disc_if(struct bcm_cfg80211 *cfg);
419 
420 extern int
421 wl_cfgp2p_start_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev);
422 
423 extern void
424 wl_cfgp2p_stop_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev);
425 
426 extern int
427 wl_cfgp2p_del_p2p_disc_if(struct wireless_dev *wdev, struct bcm_cfg80211 *cfg);
428 
429 #endif /* WL_CFG80211_P2P_DEV_IF */
430 
431 extern void
432 wl_cfgp2p_need_wait_actfrmae(struct bcm_cfg80211 *cfg, void *frame, u32 frame_len, bool tx);
433 
434 extern int
435 wl_cfgp2p_is_p2p_specific_scan(struct cfg80211_scan_request *request);
436 
437 /* WiFi Direct */
438 #define SOCIAL_CHAN_1 1
439 #define SOCIAL_CHAN_2 6
440 #define SOCIAL_CHAN_3 11
441 #define IS_P2P_SOCIAL_CHANNEL(channel) ((channel == SOCIAL_CHAN_1) || \
442                     (channel == SOCIAL_CHAN_2) || \
443                     (channel == SOCIAL_CHAN_3))
444 #define SOCIAL_CHAN_CNT 3
445 #define AF_PEER_SEARCH_CNT 2
446 #define WL_P2P_WILDCARD_SSID "DIRECT-"
447 #define WL_P2P_WILDCARD_SSID_LEN 7
448 #define WL_P2P_INTERFACE_PREFIX "p2p"
449 #define WL_P2P_TEMP_CHAN 11
450 #define WL_P2P_TEMP_CHAN_5G 36
451 #define WL_P2P_AF_STATUS_OFFSET 9
452 
453 /* If the provision discovery is for JOIN operations,
454  * or the device discoverablity frame is destined to GO
455  * then we need not do an internal scan to find GO.
456  */
457 #define IS_ACTPUB_WITHOUT_GROUP_ID(p2p_ie, len) \
458     (wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_GROUP_ID) == NULL)
459 
460 #define IS_GAS_REQ(frame, len) (wl_cfgp2p_is_gas_action(frame, len) && \
461                     ((frame->action == P2PSD_ACTION_ID_GAS_IREQ) || \
462                     (frame->action == P2PSD_ACTION_ID_GAS_CREQ)))
463 
464 #define IS_P2P_PUB_ACT_RSP_SUBTYPE(subtype) ((subtype == P2P_PAF_GON_RSP) || \
465                             ((subtype == P2P_PAF_GON_CONF) || \
466                             (subtype == P2P_PAF_INVITE_RSP) || \
467                             (subtype == P2P_PAF_PROVDIS_RSP)))
468 #define IS_P2P_SOCIAL(ch) ((ch == SOCIAL_CHAN_1) || (ch == SOCIAL_CHAN_2) || (ch == SOCIAL_CHAN_3))
469 #define IS_P2P_SSID(ssid, len) (!memcmp(ssid, WL_P2P_WILDCARD_SSID, WL_P2P_WILDCARD_SSID_LEN) && \
470                     (len == WL_P2P_WILDCARD_SSID_LEN))
471 #endif                /* _wl_cfgp2p_h_ */
472