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