• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * DHD Linux header file (dhd_linux exports for cfg80211 and other components)
4  *
5  * Copyright (C) 1999-2019, Broadcom.
6  *
7  *      Unless you and Broadcom execute a separate written software license
8  * agreement governing use of this software, this software is licensed to you
9  * under the terms of the GNU General Public License version 2 (the "GPL"),
10  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
11  * following added to such license:
12  *
13  *      As a special exception, the copyright holders of this software give you
14  * permission to link this software with independent modules, and to copy and
15  * distribute the resulting executable under terms of your choice, provided that
16  * you also meet, for each linked independent module, the terms and conditions of
17  * the license of that module.  An independent module is a module which is not
18  * derived from this software.  The special exception does not apply to any
19  * modifications of the software.
20  *
21  *      Notwithstanding the above, under no circumstances may you combine this
22  * software in any way with any other Broadcom software provided under a license
23  * other than the GPL, without Broadcom's express prior written consent.
24  *
25  *
26  * <<Broadcom-WL-IPTag/Open:>>
27  *
28  * $Id: dhd_linux.h 816392 2019-04-24 14:39:02Z $
29  */
30 
31 /* wifi platform functions for power, interrupt and pre-alloc, either
32  * from Android-like platform device data, or Broadcom wifi platform
33  * device data.
34  *
35  */
36 #ifndef __DHD_LINUX_H__
37 #define __DHD_LINUX_H__
38 
39 #include <linux/kernel.h>
40 #include <linux/init.h>
41 #include <linux/fs.h>
42 #include <dngl_stats.h>
43 #include <dhd.h>
44 /* Linux wireless extension support */
45 #if defined(WL_WIRELESS_EXT)
46 #include <wl_iw.h>
47 #endif /* defined(WL_WIRELESS_EXT) */
48 #if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND)
49 #include <linux/earlysuspend.h>
50 #endif /* defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) */
51 #ifdef PCIE_FULL_DONGLE
52 #include <etd.h>
53 #endif /* PCIE_FULL_DONGLE */
54 #ifdef WL_MONITOR
55 #include <bcmmsgbuf.h>
56 #define MAX_RADIOTAP_SIZE      256 /* Maximum size to hold HE Radiotap header format */
57 #define MAX_MON_PKT_SIZE       (4096 + MAX_RADIOTAP_SIZE)
58 #endif /* WL_MONITOR */
59 
60 #define FILE_DUMP_MAX_WAIT_TIME 4000
61 
62 #define htod32(i) (i)
63 #define htod16(i) (i)
64 #define dtoh32(i) (i)
65 #define dtoh16(i) (i)
66 #define htodchanspec(i) (i)
67 #define dtohchanspec(i) (i)
68 
69 #ifdef BLOCK_IPV6_PACKET
70 #define HEX_PREF_STR	"0x"
71 #define UNI_FILTER_STR	"010000000000"
72 #define ZERO_ADDR_STR	"000000000000"
73 #define ETHER_TYPE_STR	"0000"
74 #define IPV6_FILTER_STR	"20"
75 #define ZERO_TYPE_STR	"00"
76 #endif /* BLOCK_IPV6_PACKET */
77 
78 typedef struct dhd_if_event {
79 	struct list_head	list;
80 	wl_event_data_if_t	event;
81 	char			name[IFNAMSIZ+1];
82 	uint8			mac[ETHER_ADDR_LEN];
83 } dhd_if_event_t;
84 
85 /* Interface control information */
86 typedef struct dhd_if {
87 	struct dhd_info *info;			/* back pointer to dhd_info */
88 	/* OS/stack specifics */
89 	struct net_device *net;
90 	int				idx;			/* iface idx in dongle */
91 	uint			subunit;		/* subunit */
92 	uint8			mac_addr[ETHER_ADDR_LEN];	/* assigned MAC address */
93 	bool			set_macaddress;
94 	bool			set_multicast;
95 	uint8			bssidx;			/* bsscfg index for the interface */
96 	bool			attached;		/* Delayed attachment when unset */
97 	bool			txflowcontrol;	/* Per interface flow control indicator */
98 	char			name[IFNAMSIZ+1]; /* linux interface name */
99 	char			dngl_name[IFNAMSIZ+1]; /* corresponding dongle interface name */
100 	struct net_device_stats stats;
101 #ifdef PCIE_FULL_DONGLE
102 	struct list_head sta_list;		/* sll of associated stations */
103 	spinlock_t	sta_list_lock;		/* lock for manipulating sll */
104 #endif /* PCIE_FULL_DONGLE */
105 	uint32  ap_isolate;			/* ap-isolation settings */
106 #ifdef DHD_L2_FILTER
107 	bool parp_enable;
108 	bool parp_discard;
109 	bool parp_allnode;
110 	arp_table_t *phnd_arp_table;
111 	/* for Per BSS modification */
112 	bool dhcp_unicast;
113 	bool block_ping;
114 	bool grat_arp;
115 	bool block_tdls;
116 #endif /* DHD_L2_FILTER */
117 #ifdef DHD_MCAST_REGEN
118 	bool mcast_regen_bss_enable;
119 #endif // endif
120 	bool rx_pkt_chainable;		/* set all rx packet to chainable config by default */
121 	cumm_ctr_t cumm_ctr;		/* cummulative queue length of child flowrings */
122 	uint8 tx_paths_active;
123 	bool del_in_progress;
124 	bool static_if;			/* used to avoid some operations on static_if */
125 #ifdef DHD_4WAYM4_FAIL_DISCONNECT
126 	struct delayed_work m4state_work;
127 	atomic_t m4state;
128 #endif /* DHD_4WAYM4_FAIL_DISCONNECT */
129 #ifdef DHD_POST_EAPOL_M1_AFTER_ROAM_EVT
130 	bool recv_reassoc_evt;
131 	bool post_roam_evt;
132 #endif /* DHD_POST_EAPOL_M1_AFTER_ROAM_EVT */
133 #ifdef DHDTCPSYNC_FLOOD_BLK
134 	uint32 tsync_rcvd;
135 	uint32 tsyncack_txed;
136 	u64 last_sync;
137 	struct work_struct  blk_tsfl_work;
138 #endif /* DHDTCPSYNC_FLOOD_BLK */
139 } dhd_if_t;
140 
141 struct ipv6_work_info_t {
142 	uint8			if_idx;
143 	char			ipv6_addr[IPV6_ADDR_LEN];
144 	unsigned long		event;
145 };
146 
147 typedef struct dhd_dump {
148 	uint8 *buf;
149 	int bufsize;
150 	uint8 *hscb_buf;
151 	int hscb_bufsize;
152 } dhd_dump_t;
153 #ifdef DNGL_AXI_ERROR_LOGGING
154 typedef struct dhd_axi_error_dump {
155 	ulong fault_address;
156 	uint32 axid;
157 	struct hnd_ext_trap_axi_error_v1 etd_axi_error_v1;
158 } dhd_axi_error_dump_t;
159 #endif /* DNGL_AXI_ERROR_LOGGING */
160 
161 #ifdef DHD_PCIE_NATIVE_RUNTIMEPM
162 struct dhd_rx_tx_work {
163 	struct work_struct work;
164 	struct sk_buff *skb;
165 	struct net_device *net;
166 	struct dhd_pub *pub;
167 };
168 #endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
169 
170 #if defined(DHD_LB)
171 #if !defined(PCIE_FULL_DONGLE)
172 #error "DHD Loadbalancing only supported on PCIE_FULL_DONGLE"
173 #endif /* !PCIE_FULL_DONGLE */
174 #endif /* DHD_LB */
175 
176 #if defined(DHD_LB_RXP) || defined(DHD_LB_RXC) || defined(DHD_LB_TXC) || \
177 	defined(DHD_LB_STATS)
178 #if !defined(DHD_LB)
179 #error "DHD loadbalance derivatives are supported only if DHD_LB is defined"
180 #endif /* !DHD_LB */
181 #endif /* DHD_LB_RXP || DHD_LB_RXC || DHD_LB_TXC || DHD_LB_STATS */
182 
183 #if defined(DHD_LB)
184 /* Dynamic CPU selection for load balancing */
185 #include <linux/cpu.h>
186 #include <linux/cpumask.h>
187 #include <linux/notifier.h>
188 #include <linux/workqueue.h>
189 #include <asm/atomic.h>
190 
191 #if !defined(DHD_LB_PRIMARY_CPUS)
192 #define DHD_LB_PRIMARY_CPUS     0x0 /* Big CPU coreids mask */
193 #endif // endif
194 #if !defined(DHD_LB_SECONDARY_CPUS)
195 #define DHD_LB_SECONDARY_CPUS   0xFE /* Little CPU coreids mask */
196 #endif // endif
197 
198 #define HIST_BIN_SIZE	9
199 
200 #if defined(DHD_LB_TXP)
201 /* Pkttag not compatible with PROP_TXSTATUS or WLFC */
202 typedef struct dhd_tx_lb_pkttag_fr {
203 	struct net_device *net;
204 	int ifidx;
205 } dhd_tx_lb_pkttag_fr_t;
206 
207 #define DHD_LB_TX_PKTTAG_SET_NETDEV(tag, netdevp)	((tag)->net = netdevp)
208 #define DHD_LB_TX_PKTTAG_NETDEV(tag)			((tag)->net)
209 
210 #define DHD_LB_TX_PKTTAG_SET_IFIDX(tag, ifidx)	((tag)->ifidx = ifidx)
211 #define DHD_LB_TX_PKTTAG_IFIDX(tag)		((tag)->ifidx)
212 #endif /* DHD_LB_TXP */
213 
214 #endif /* DHD_LB */
215 
216 #ifdef FILTER_IE
217 #define FILTER_IE_PATH "/etc/wifi/filter_ie"
218 #define FILTER_IE_BUFSZ 1024 /* ioc buffsize for FILTER_IE */
219 #define FILE_BLOCK_READ_SIZE 256
220 #define WL_FILTER_IE_IOV_HDR_SIZE OFFSETOF(wl_filter_ie_iov_v1_t, tlvs)
221 #endif /* FILTER_IE */
222 
223 #define NULL_CHECK(p, s, err)  \
224 			do { \
225 				if (!(p)) { \
226 					printk("NULL POINTER (%s) : %s\n", __FUNCTION__, (s)); \
227 					err = BCME_ERROR; \
228 					return err; \
229 				} \
230 			} while (0)
231 
232 /* dongle status */
233 enum wifi_adapter_status {
234 	WIFI_STATUS_POWER_ON = 0,
235 	WIFI_STATUS_ATTACH,
236 	WIFI_STATUS_FW_READY,
237 	WIFI_STATUS_DETTACH
238 };
239 #define wifi_chk_adapter_status(adapter, stat) (test_bit(stat, &(adapter)->status))
240 #define wifi_get_adapter_status(adapter, stat) (test_bit(stat, &(adapter)->status))
241 #define wifi_set_adapter_status(adapter, stat) (set_bit(stat, &(adapter)->status))
242 #define wifi_clr_adapter_status(adapter, stat) (clear_bit(stat, &(adapter)->status))
243 #define wifi_chg_adapter_status(adapter, stat) (change_bit(stat, &(adapter)->status))
244 
245 #define DHD_REGISTRATION_TIMEOUT  12000  /* msec : allowed time to finished dhd registration */
246 #define DHD_FW_READY_TIMEOUT  5000  /* msec : allowed time to finished fw download */
247 
248 typedef struct wifi_adapter_info {
249 	const char	*name;
250 	uint		irq_num;
251 	uint		intr_flags;
252 	const char	*fw_path;
253 	const char	*nv_path;
254 	const char	*clm_path;
255 	const char	*conf_path;
256 	void		*wifi_plat_data;	/* wifi ctrl func, for backward compatibility */
257 	uint		bus_type;
258 	uint		bus_num;
259 	uint		slot_num;
260 	wait_queue_head_t status_event;
261 	unsigned long status;
262 #if defined(BT_OVER_SDIO)
263 	const char	*btfw_path;
264 #endif /* defined (BT_OVER_SDIO) */
265 #if defined(BCMSDIO)
266 	struct sdio_func *sdio_func;
267 #endif /* BCMSDIO */
268 #if defined(BCMPCIE)
269 	struct pci_dev *pci_dev;
270 	struct pci_saved_state *pci_saved_state;
271 #endif /* BCMPCIE */
272 } wifi_adapter_info_t;
273 
274 #define WLAN_PLAT_NODFS_FLAG	0x01
275 #define WLAN_PLAT_AP_FLAG	0x02
276 #if !defined(CONFIG_WIFI_CONTROL_FUNC)
277 struct wifi_platform_data {
278 #ifdef BUS_POWER_RESTORE
279 	int (*set_power)(int val, wifi_adapter_info_t *adapter);
280 #else
281 	int (*set_power)(int val);
282 #endif
283 	int (*set_reset)(int val);
284 	int (*set_carddetect)(int val);
285 	void *(*mem_prealloc)(int section, unsigned long size);
286 #ifdef CUSTOM_MULTI_MAC
287 	int (*get_mac_addr)(unsigned char *buf, char *name);
288 #else
289 	int (*get_mac_addr)(unsigned char *buf);
290 #endif
291 #ifdef BCMSDIO
292 	int (*get_wake_irq)(void);
293 #endif // endif
294 #ifdef CUSTOM_FORCE_NODFS_FLAG
295 	void *(*get_country_code)(char *ccode, u32 flags);
296 #else /* defined (CUSTOM_FORCE_NODFS_FLAG) */
297 	void *(*get_country_code)(char *ccode);
298 #endif
299 };
300 #endif
301 
302 typedef struct bcmdhd_wifi_platdata {
303 	uint				num_adapters;
304 	wifi_adapter_info_t	*adapters;
305 } bcmdhd_wifi_platdata_t;
306 
307 /** Per STA params. A list of dhd_sta objects are managed in dhd_if */
308 typedef struct dhd_sta {
309 	cumm_ctr_t cumm_ctr;    /* cummulative queue length of child flowrings */
310 	uint16 flowid[NUMPRIO]; /* allocated flow ring ids (by priority) */
311 	void * ifp;             /* associated dhd_if */
312 	struct ether_addr ea;   /* stations ethernet mac address */
313 	struct list_head list;  /* link into dhd_if::sta_list */
314 	int idx;                /* index of self in dhd_pub::sta_pool[] */
315 	int ifidx;              /* index of interface in dhd */
316 } dhd_sta_t;
317 typedef dhd_sta_t dhd_sta_pool_t;
318 
319 #ifdef DHD_4WAYM4_FAIL_DISCONNECT
320 typedef enum {
321 	M3_RXED,
322 	M4_TXFAILED
323 } msg_4way_state_t;
324 #define MAX_4WAY_TIMEOUT_MS 2000
325 #endif /* DHD_4WAYM4_FAIL_DISCONNECT */
326 
327 #ifdef DHD_SEND_HANG_PRIVCMD_ERRORS
328 extern uint32 report_hang_privcmd_err;
329 #endif /* DHD_SEND_HANG_PRIVCMD_ERRORS */
330 
331 #if defined(ARGOS_NOTIFY_CB)
332 int argos_register_notifier_init(struct net_device *net);
333 int argos_register_notifier_deinit(void);
334 
335 extern int sec_argos_register_notifier(struct notifier_block *n, char *label);
336 extern int sec_argos_unregister_notifier(struct notifier_block *n, char *label);
337 
338 typedef struct {
339 	struct net_device *wlan_primary_netdev;
340 	int argos_rps_cpus_enabled;
341 } argos_rps_ctrl;
342 
343 #define RPS_TPUT_THRESHOLD		300
344 #define DELAY_TO_CLEAR_RPS_CPUS		300
345 #endif // endif
346 
347 #if defined(BT_OVER_SDIO)
348 extern void wl_android_set_wifi_on_flag(bool enable);
349 #endif /* BT_OVER_SDIO */
350 
351 #ifdef DHD_LOG_DUMP
352 /* 0: DLD_BUF_TYPE_GENERAL, 1: DLD_BUF_TYPE_PRESERVE
353 * 2: DLD_BUF_TYPE_SPECIAL
354 */
355 #define DLD_BUFFER_NUM 3
356 
357 #ifndef CUSTOM_LOG_DUMP_BUFSIZE_MB
358 #define CUSTOM_LOG_DUMP_BUFSIZE_MB	4 /* DHD_LOG_DUMP_BUF_SIZE 4 MB static memory in kernel */
359 #endif /* CUSTOM_LOG_DUMP_BUFSIZE_MB */
360 
361 #define LOG_DUMP_TOTAL_BUFSIZE (1024 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
362 
363 /*
364  * Below are different sections that use the prealloced buffer
365  * and sum of the sizes of these should not cross LOG_DUMP_TOTAL_BUFSIZE
366  */
367 #define LOG_DUMP_GENERAL_MAX_BUFSIZE (256 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
368 #define LOG_DUMP_PRESERVE_MAX_BUFSIZE (128 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
369 #define LOG_DUMP_ECNTRS_MAX_BUFSIZE (256 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
370 #define LOG_DUMP_RTT_MAX_BUFSIZE (256 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
371 #define LOG_DUMP_FILTER_MAX_BUFSIZE (128 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
372 
373 #if LOG_DUMP_TOTAL_BUFSIZE < (LOG_DUMP_GENERAL_MAX_BUFSIZE + \
374 	LOG_DUMP_PRESERVE_MAX_BUFSIZE + LOG_DUMP_ECNTRS_MAX_BUFSIZE + LOG_DUMP_RTT_MAX_BUFSIZE \
375 	+ LOG_DUMP_FILTER_MAX_BUFSIZE)
376 #error "LOG_DUMP_TOTAL_BUFSIZE is lesser than sum of all rings"
377 #endif // endif
378 
379 /* Special buffer is allocated as separately in prealloc */
380 #define LOG_DUMP_SPECIAL_MAX_BUFSIZE (8 * 1024)
381 
382 #define LOG_DUMP_MAX_FILESIZE (8 *1024 * 1024) /* 8 MB default */
383 #ifdef CONFIG_LOG_BUF_SHIFT
384 /* 15% of kernel log buf size, if for example klog buf size is 512KB
385 * 15% of 512KB ~= 80KB
386 */
387 #define LOG_DUMP_KERNEL_TAIL_FLUSH_SIZE \
388 	(15 * ((1 << CONFIG_LOG_BUF_SHIFT)/100))
389 #endif /* CONFIG_LOG_BUF_SHIFT */
390 
391 #define LOG_DUMP_COOKIE_BUFSIZE	1024u
392 
393 typedef struct {
394 	char *hdr_str;
395 	log_dump_section_type_t sec_type;
396 } dld_hdr_t;
397 
398 typedef struct {
399 	int attr;
400 	char *hdr_str;
401 	log_dump_section_type_t sec_type;
402 	int log_type;
403 } dld_log_hdr_t;
404 
405 #define DHD_PRINT_BUF_NAME_LEN 30
406 #endif /* DHD_LOG_DUMP */
407 
408 int dhd_wifi_platform_register_drv(void);
409 void dhd_wifi_platform_unregister_drv(void);
410 wifi_adapter_info_t* dhd_wifi_platform_attach_adapter(uint32 bus_type,
411 	uint32 bus_num, uint32 slot_num, unsigned long status);
412 wifi_adapter_info_t* dhd_wifi_platform_get_adapter(uint32 bus_type, uint32 bus_num,
413 	uint32 slot_num);
414 int wifi_platform_set_power(wifi_adapter_info_t *adapter, bool on, unsigned long msec);
415 int wifi_platform_bus_enumerate(wifi_adapter_info_t *adapter, bool device_present);
416 int wifi_platform_get_irq_number(wifi_adapter_info_t *adapter, unsigned long *irq_flags_ptr);
417 int wifi_platform_get_mac_addr(wifi_adapter_info_t *adapter, unsigned char *buf, char *name);
418 #ifdef CUSTOM_COUNTRY_CODE
419 void *wifi_platform_get_country_code(wifi_adapter_info_t *adapter, char *ccode,
420 	u32 flags);
421 #else
422 void *wifi_platform_get_country_code(wifi_adapter_info_t *adapter, char *ccode);
423 #endif /* CUSTOM_COUNTRY_CODE */
424 void* wifi_platform_prealloc(wifi_adapter_info_t *adapter, int section, unsigned long size);
425 void* wifi_platform_get_prealloc_func_ptr(wifi_adapter_info_t *adapter);
426 
427 int dhd_get_fw_mode(struct dhd_info *dhdinfo);
428 bool dhd_update_fw_nv_path(struct dhd_info *dhdinfo);
429 
430 #if defined(BT_OVER_SDIO)
431 int dhd_net_bus_get(struct net_device *dev);
432 int dhd_net_bus_put(struct net_device *dev);
433 #endif /* BT_OVER_SDIO */
434 #if defined(WLADPS)
435 #define ADPS_ENABLE	1
436 #define ADPS_DISABLE	0
437 
438 int dhd_enable_adps(dhd_pub_t *dhd, uint8 on);
439 #endif // endif
440 #ifdef DHDTCPSYNC_FLOOD_BLK
441 extern void dhd_reset_tcpsync_info_by_ifp(dhd_if_t *ifp);
442 extern void dhd_reset_tcpsync_info_by_dev(struct net_device *dev);
443 #endif /* DHDTCPSYNC_FLOOD_BLK */
444 
445 int compat_kernel_read(struct file *file, loff_t offset, char *addr, unsigned long count);
446 int compat_vfs_write(struct file *file, char *addr, int count, loff_t *offset);
447 
448 #endif /* __DHD_LINUX_H__ */
449