1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #ifndef _wl_cfg80211_h_
18 #define _wl_cfg80211_h_
19 
20 struct brcmf_cfg80211_conf;
21 struct brcmf_cfg80211_iface;
22 struct brcmf_cfg80211_priv;
23 struct brcmf_cfg80211_security;
24 struct brcmf_cfg80211_ibss;
25 
26 #define WL_DBG_NONE		0
27 #define WL_DBG_CONN		(1 << 5)
28 #define WL_DBG_SCAN		(1 << 4)
29 #define WL_DBG_TRACE		(1 << 3)
30 #define WL_DBG_INFO		(1 << 1)
31 #define WL_DBG_ERR		(1 << 0)
32 #define WL_DBG_MASK		((WL_DBG_INFO | WL_DBG_ERR | WL_DBG_TRACE) | \
33 				(WL_DBG_SCAN) | (WL_DBG_CONN))
34 
35 #define	WL_ERR(fmt, ...)					\
36 do {								\
37 	if (brcmf_dbg_level & WL_DBG_ERR) {			\
38 		if (net_ratelimit()) {				\
39 			pr_err("ERROR @%s : " fmt,		\
40 			       __func__, ##__VA_ARGS__);	\
41 		}						\
42 	}							\
43 } while (0)
44 
45 #if (defined DEBUG)
46 #define	WL_INFO(fmt, ...)					\
47 do {								\
48 	if (brcmf_dbg_level & WL_DBG_INFO) {			\
49 		if (net_ratelimit()) {				\
50 			pr_err("INFO @%s : " fmt,		\
51 			       __func__, ##__VA_ARGS__);	\
52 		}						\
53 	}							\
54 } while (0)
55 
56 #define	WL_TRACE(fmt, ...)					\
57 do {								\
58 	if (brcmf_dbg_level & WL_DBG_TRACE) {			\
59 		if (net_ratelimit()) {				\
60 			pr_err("TRACE @%s : " fmt,		\
61 			       __func__, ##__VA_ARGS__);	\
62 		}						\
63 	}							\
64 } while (0)
65 
66 #define	WL_SCAN(fmt, ...)					\
67 do {								\
68 	if (brcmf_dbg_level & WL_DBG_SCAN) {			\
69 		if (net_ratelimit()) {				\
70 			pr_err("SCAN @%s : " fmt,		\
71 			       __func__, ##__VA_ARGS__);	\
72 		}						\
73 	}							\
74 } while (0)
75 
76 #define	WL_CONN(fmt, ...)					\
77 do {								\
78 	if (brcmf_dbg_level & WL_DBG_CONN) {			\
79 		if (net_ratelimit()) {				\
80 			pr_err("CONN @%s : " fmt,		\
81 			       __func__, ##__VA_ARGS__);	\
82 		}						\
83 	}							\
84 } while (0)
85 
86 #else /* (defined DEBUG) */
87 #define	WL_INFO(fmt, args...)
88 #define	WL_TRACE(fmt, args...)
89 #define	WL_SCAN(fmt, args...)
90 #define	WL_CONN(fmt, args...)
91 #endif /* (defined DEBUG) */
92 
93 #define WL_NUM_SCAN_MAX		1
94 #define WL_NUM_PMKIDS_MAX	MAXPMKID	/* will be used
95 						 * for 2.6.33 kernel
96 						 * or later
97 						 */
98 #define WL_SCAN_BUF_MAX			(1024 * 8)
99 #define WL_TLV_INFO_MAX			1024
100 #define WL_BSS_INFO_MAX			2048
101 #define WL_ASSOC_INFO_MAX	512	/*
102 				 * needs to grab assoc info from dongle to
103 				 * report it to cfg80211 through "connect"
104 				 * event
105 				 */
106 #define WL_DCMD_LEN_MAX	1024
107 #define WL_EXTRA_BUF_MAX	2048
108 #define WL_ISCAN_BUF_MAX	2048	/*
109 				 * the buf length can be BRCMF_DCMD_MAXLEN
110 				 * to reduce iteration
111 				 */
112 #define WL_ISCAN_TIMER_INTERVAL_MS	3000
113 #define WL_SCAN_ERSULTS_LAST	(BRCMF_SCAN_RESULTS_NO_MEM+1)
114 #define WL_AP_MAX	256	/* virtually unlimitted as long
115 				 * as kernel memory allows
116 				 */
117 
118 #define WL_ROAM_TRIGGER_LEVEL		-75
119 #define WL_ROAM_DELTA			20
120 #define WL_BEACON_TIMEOUT		3
121 
122 #define WL_SCAN_CHANNEL_TIME		40
123 #define WL_SCAN_UNASSOC_TIME		40
124 #define WL_SCAN_PASSIVE_TIME		120
125 
126 /* dongle status */
127 enum wl_status {
128 	WL_STATUS_READY,
129 	WL_STATUS_SCANNING,
130 	WL_STATUS_SCAN_ABORTING,
131 	WL_STATUS_CONNECTING,
132 	WL_STATUS_CONNECTED
133 };
134 
135 /* wi-fi mode */
136 enum wl_mode {
137 	WL_MODE_BSS,
138 	WL_MODE_IBSS,
139 	WL_MODE_AP
140 };
141 
142 /* dongle profile list */
143 enum wl_prof_list {
144 	WL_PROF_MODE,
145 	WL_PROF_SSID,
146 	WL_PROF_SEC,
147 	WL_PROF_IBSS,
148 	WL_PROF_BAND,
149 	WL_PROF_BSSID,
150 	WL_PROF_ACT,
151 	WL_PROF_BEACONINT,
152 	WL_PROF_DTIMPERIOD
153 };
154 
155 /* dongle iscan state */
156 enum wl_iscan_state {
157 	WL_ISCAN_STATE_IDLE,
158 	WL_ISCAN_STATE_SCANING
159 };
160 
161 /* dongle configuration */
162 struct brcmf_cfg80211_conf {
163 	u32 mode;		/* adhoc , infrastructure or ap */
164 	u32 frag_threshold;
165 	u32 rts_threshold;
166 	u32 retry_short;
167 	u32 retry_long;
168 	s32 tx_power;
169 	struct ieee80211_channel channel;
170 };
171 
172 /* cfg80211 main event loop */
173 struct brcmf_cfg80211_event_loop {
174 	s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_priv *cfg_priv,
175 				     struct net_device *ndev,
176 				     const struct brcmf_event_msg *e,
177 				     void *data);
178 };
179 
180 /* representing interface of cfg80211 plane */
181 struct brcmf_cfg80211_iface {
182 	struct brcmf_cfg80211_priv *cfg_priv;
183 };
184 
185 struct brcmf_cfg80211_dev {
186 	void *driver_data;	/* to store cfg80211 object information */
187 };
188 
189 /* basic structure of scan request */
190 struct brcmf_cfg80211_scan_req {
191 	struct brcmf_ssid_le ssid_le;
192 };
193 
194 /* basic structure of information element */
195 struct brcmf_cfg80211_ie {
196 	u16 offset;
197 	u8 buf[WL_TLV_INFO_MAX];
198 };
199 
200 /* event queue for cfg80211 main event */
201 struct brcmf_cfg80211_event_q {
202 	struct list_head evt_q_list;
203 	u32 etype;
204 	struct brcmf_event_msg emsg;
205 	s8 edata[1];
206 };
207 
208 /* security information with currently associated ap */
209 struct brcmf_cfg80211_security {
210 	u32 wpa_versions;
211 	u32 auth_type;
212 	u32 cipher_pairwise;
213 	u32 cipher_group;
214 	u32 wpa_auth;
215 };
216 
217 /* ibss information for currently joined ibss network */
218 struct brcmf_cfg80211_ibss {
219 	u8 beacon_interval;	/* in millisecond */
220 	u8 atim;		/* in millisecond */
221 	s8 join_only;
222 	u8 band;
223 	u8 channel;
224 };
225 
226 /* dongle profile */
227 struct brcmf_cfg80211_profile {
228 	u32 mode;
229 	struct brcmf_ssid ssid;
230 	u8 bssid[ETH_ALEN];
231 	u16 beacon_interval;
232 	u8 dtim_period;
233 	struct brcmf_cfg80211_security sec;
234 	struct brcmf_cfg80211_ibss ibss;
235 	s32 band;
236 };
237 
238 /* dongle iscan event loop */
239 struct brcmf_cfg80211_iscan_eloop {
240 	s32 (*handler[WL_SCAN_ERSULTS_LAST])
241 		(struct brcmf_cfg80211_priv *cfg_priv);
242 };
243 
244 /* dongle iscan controller */
245 struct brcmf_cfg80211_iscan_ctrl {
246 	struct net_device *ndev;
247 	struct timer_list timer;
248 	u32 timer_ms;
249 	u32 timer_on;
250 	s32 state;
251 	struct work_struct work;
252 	struct brcmf_cfg80211_iscan_eloop el;
253 	void *data;
254 	s8 dcmd_buf[BRCMF_DCMD_SMLEN];
255 	s8 scan_buf[WL_ISCAN_BUF_MAX];
256 };
257 
258 /* association inform */
259 struct brcmf_cfg80211_connect_info {
260 	u8 *req_ie;
261 	s32 req_ie_len;
262 	u8 *resp_ie;
263 	s32 resp_ie_len;
264 };
265 
266 /* assoc ie length */
267 struct brcmf_cfg80211_assoc_ielen_le {
268 	__le32 req_len;
269 	__le32 resp_len;
270 };
271 
272 /* wpa2 pmk list */
273 struct brcmf_cfg80211_pmk_list {
274 	struct pmkid_list pmkids;
275 	struct pmkid foo[MAXPMKID - 1];
276 };
277 
278 /* dongle private data of cfg80211 interface */
279 struct brcmf_cfg80211_priv {
280 	struct wireless_dev *wdev;	/* representing wl cfg80211 device */
281 	struct brcmf_cfg80211_conf *conf;	/* dongle configuration */
282 	struct cfg80211_scan_request *scan_request;	/* scan request
283 							 object */
284 	struct brcmf_cfg80211_event_loop el;	/* main event loop */
285 	struct list_head evt_q_list;	/* used for event queue */
286 	spinlock_t	 evt_q_lock;	/* for event queue synchronization */
287 	struct mutex usr_sync;	/* maily for dongle up/down synchronization */
288 	struct brcmf_scan_results *bss_list;	/* bss_list holding scanned
289 						 ap information */
290 	struct brcmf_scan_results *scan_results;
291 	struct brcmf_cfg80211_scan_req *scan_req_int;	/* scan request object
292 						 for internal purpose */
293 	struct wl_cfg80211_bss_info *bss_info;	/* bss information for
294 						 cfg80211 layer */
295 	struct brcmf_cfg80211_ie ie;	/* information element object for
296 					 internal purpose */
297 	struct brcmf_cfg80211_profile *profile;	/* holding dongle profile */
298 	struct brcmf_cfg80211_iscan_ctrl *iscan;	/* iscan controller */
299 	struct brcmf_cfg80211_connect_info conn_info; /* association info */
300 	struct brcmf_cfg80211_pmk_list *pmk_list;	/* wpa2 pmk list */
301 	struct work_struct event_work;	/* event handler work struct */
302 	unsigned long status;		/* current dongle status */
303 	void *pub;
304 	u32 channel;		/* current channel */
305 	bool iscan_on;		/* iscan on/off switch */
306 	bool iscan_kickstart;	/* indicate iscan already started */
307 	bool active_scan;	/* current scan mode */
308 	bool ibss_starter;	/* indicates this sta is ibss starter */
309 	bool link_up;		/* link/connection up flag */
310 	bool pwr_save;		/* indicate whether dongle to support
311 					 power save mode */
312 	bool dongle_up;		/* indicate whether dongle up or not */
313 	bool roam_on;		/* on/off switch for dongle self-roaming */
314 	bool scan_tried;	/* indicates if first scan attempted */
315 	u8 *dcmd_buf;		/* dcmd buffer */
316 	u8 *extra_buf;		/* maily to grab assoc information */
317 	struct dentry *debugfsdir;
318 	u8 ci[0] __aligned(NETDEV_ALIGN);
319 };
320 
cfg_to_wiphy(struct brcmf_cfg80211_priv * w)321 static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_priv *w)
322 {
323 	return w->wdev->wiphy;
324 }
325 
wiphy_to_cfg(struct wiphy * w)326 static inline struct brcmf_cfg80211_priv *wiphy_to_cfg(struct wiphy *w)
327 {
328 	return (struct brcmf_cfg80211_priv *)(wiphy_priv(w));
329 }
330 
wdev_to_cfg(struct wireless_dev * wd)331 static inline struct brcmf_cfg80211_priv *wdev_to_cfg(struct wireless_dev *wd)
332 {
333 	return (struct brcmf_cfg80211_priv *)(wdev_priv(wd));
334 }
335 
cfg_to_ndev(struct brcmf_cfg80211_priv * cfg)336 static inline struct net_device *cfg_to_ndev(struct brcmf_cfg80211_priv *cfg)
337 {
338 	return cfg->wdev->netdev;
339 }
340 
ndev_to_cfg(struct net_device * ndev)341 static inline struct brcmf_cfg80211_priv *ndev_to_cfg(struct net_device *ndev)
342 {
343 	return wdev_to_cfg(ndev->ieee80211_ptr);
344 }
345 
346 #define iscan_to_cfg(i) ((struct brcmf_cfg80211_priv *)(i->data))
347 #define cfg_to_iscan(w) (w->iscan)
348 
349 static inline struct
cfg_to_conn(struct brcmf_cfg80211_priv * cfg)350 brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_priv *cfg)
351 {
352 	return &cfg->conn_info;
353 }
354 
355 extern struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
356 							struct device *busdev,
357 							void *data);
358 extern void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg);
359 
360 /* event handler from dongle */
361 extern void brcmf_cfg80211_event(struct net_device *ndev,
362 				 const struct brcmf_event_msg *e, void *data);
363 extern s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev);
364 extern s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev);
365 
366 #endif				/* _wl_cfg80211_h_ */
367