• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * DHD Linux header file (dhd_linux exports for cfg80211 and other components)
3  *
4  * Copyright (C) 1999-2019, Broadcom.
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
16  * of the license of that module.  An independent module is a module which is
17  * not 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: dhd_linux.h 816392 2019-04-24 14:39:02Z $
28  */
29 
30 /* wifi platform functions for power, interrupt and pre-alloc, either
31  * from Android-like platform device data, or Broadcom wifi platform
32  * device data.
33  *
34  */
35 #ifndef __DHD_LINUX_H__
36 #define __DHD_LINUX_H__
37 
38 #include <linux/kernel.h>
39 #include <linux/init.h>
40 #include <linux/fs.h>
41 #include <dngl_stats.h>
42 #include <dhd.h>
43 /* Linux wireless extension support */
44 #if defined(WL_WIRELESS_EXT)
45 #include <wl_iw.h>
46 #endif /* defined(WL_WIRELESS_EXT) */
47 #if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND)
48 #include <linux/earlysuspend.h>
49 #endif /* defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) */
50 #ifdef PCIE_FULL_DONGLE
51 #include <etd.h>
52 #endif /* PCIE_FULL_DONGLE */
53 #ifdef WL_MONITOR
54 #include <bcmmsgbuf.h>
55 #define MAX_RADIOTAP_SIZE                                                      \
56     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
121         rx_pkt_chainable; /* set all rx packet to chainable config by default */
122     cumm_ctr_t cumm_ctr;  /* cummulative queue length of child flowrings */
123     uint8 tx_paths_active;
124     bool del_in_progress;
125     bool static_if; /* used to avoid some operations on static_if */
126 #ifdef DHD_4WAYM4_FAIL_DISCONNECT
127     struct delayed_work m4state_work;
128     atomic_t m4state;
129 #endif /* DHD_4WAYM4_FAIL_DISCONNECT */
130 #ifdef DHD_POST_EAPOL_M1_AFTER_ROAM_EVT
131     bool recv_reassoc_evt;
132     bool post_roam_evt;
133 #endif /* DHD_POST_EAPOL_M1_AFTER_ROAM_EVT */
134 #ifdef DHDTCPSYNC_FLOOD_BLK
135     uint32 tsync_rcvd;
136     uint32 tsyncack_txed;
137     u64 last_sync;
138     struct work_struct blk_tsfl_work;
139 #endif /* DHDTCPSYNC_FLOOD_BLK */
140 #ifdef WLEASYMESH
141     uint8 _1905_al_ucast[ETHER_ADDR_LEN];
142     uint8 _1905_al_mcast[ETHER_ADDR_LEN];
143 #endif /* WLEASYMESH */
144 } dhd_if_t;
145 
146 struct ipv6_work_info_t {
147     uint8 if_idx;
148     char ipv6_addr[IPV6_ADDR_LEN];
149     unsigned long event;
150 };
151 
152 typedef struct dhd_dump {
153     uint8 *buf;
154     int bufsize;
155     uint8 *hscb_buf;
156     int hscb_bufsize;
157 } dhd_dump_t;
158 #ifdef DNGL_AXI_ERROR_LOGGING
159 typedef struct dhd_axi_error_dump {
160     ulong fault_address;
161     uint32 axid;
162     struct hnd_ext_trap_axi_error_v1 etd_axi_error_v1;
163 } dhd_axi_error_dump_t;
164 #endif /* DNGL_AXI_ERROR_LOGGING */
165 
166 #ifdef DHD_PCIE_NATIVE_RUNTIMEPM
167 struct dhd_rx_tx_work {
168     struct work_struct work;
169     struct sk_buff *skb;
170     struct net_device *net;
171     struct dhd_pub *pub;
172 };
173 #endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
174 
175 #if defined(DHD_LB)
176 #if !defined(PCIE_FULL_DONGLE)
177 #error "DHD Loadbalancing only supported on PCIE_FULL_DONGLE"
178 #endif /* !PCIE_FULL_DONGLE */
179 #endif /* DHD_LB */
180 
181 #if defined(DHD_LB_RXP) || defined(DHD_LB_RXC) || defined(DHD_LB_TXC) ||       \
182     defined(DHD_LB_STATS)
183 #if !defined(DHD_LB)
184 #error "DHD loadbalance derivatives are supported only if DHD_LB is defined"
185 #endif /* !DHD_LB */
186 #endif /* DHD_LB_RXP || DHD_LB_RXC || DHD_LB_TXC || DHD_LB_STATS */
187 
188 #if defined(DHD_LB)
189 /* Dynamic CPU selection for load balancing */
190 #include <linux/cpu.h>
191 #include <linux/cpumask.h>
192 #include <linux/notifier.h>
193 #include <linux/workqueue.h>
194 #include <asm/atomic.h>
195 
196 #if !defined(DHD_LB_PRIMARY_CPUS)
197 #define DHD_LB_PRIMARY_CPUS 0x0 /* Big CPU coreids mask */
198 #endif                          // endif
199 #if !defined(DHD_LB_SECONDARY_CPUS)
200 #define DHD_LB_SECONDARY_CPUS 0xFE /* Little CPU coreids mask */
201 #endif                             // endif
202 
203 #define HIST_BIN_SIZE 9
204 
205 #if defined(DHD_LB_TXP)
206 /* Pkttag not compatible with PROP_TXSTATUS or WLFC */
207 typedef struct dhd_tx_lb_pkttag_fr {
208     struct net_device *net;
209     int ifidx;
210 } dhd_tx_lb_pkttag_fr_t;
211 
212 #define DHD_LB_TX_PKTTAG_SET_NETDEV(tag, netdevp) ((tag)->net = netdevp)
213 #define DHD_LB_TX_PKTTAG_NETDEV(tag) ((tag)->net)
214 
215 #define DHD_LB_TX_PKTTAG_SET_IFIDX(tag, ifidx) ((tag)->ifidx = ifidx)
216 #define DHD_LB_TX_PKTTAG_IFIDX(tag) ((tag)->ifidx)
217 #endif /* DHD_LB_TXP */
218 
219 #endif /* DHD_LB */
220 
221 #ifdef FILTER_IE
222 #define FILTER_IE_PATH "/etc/wifi/filter_ie"
223 #define FILTER_IE_BUFSZ 1024 /* ioc buffsize for FILTER_IE */
224 #define FILE_BLOCK_READ_SIZE 256
225 #define WL_FILTER_IE_IOV_HDR_SIZE OFFSETOF(wl_filter_ie_iov_v1_t, tlvs)
226 #endif /* FILTER_IE */
227 
228 #define NULL_CHECK(p, s, err)                                                  \
229     do {                                                                       \
230         if (!(p)) {                                                            \
231             printk("NULL POINTER (%s) : %s\n", __FUNCTION__, (s));             \
232             err = BCME_ERROR;                                                  \
233             return err;                                                        \
234         }                                                                      \
235     } while (0)
236 
237 /* dongle status */
238 enum wifi_adapter_status {
239     WIFI_STATUS_POWER_ON = 0,
240     WIFI_STATUS_ATTACH,
241     WIFI_STATUS_FW_READY,
242     WIFI_STATUS_DETTACH
243 };
244 #define wifi_chk_adapter_status(adapter, stat)                                 \
245     (test_bit(stat, &(adapter)->status))
246 #define wifi_get_adapter_status(adapter, stat)                                 \
247     (test_bit(stat, &(adapter)->status))
248 #define wifi_set_adapter_status(adapter, stat)                                 \
249     (set_bit(stat, &(adapter)->status))
250 #define wifi_clr_adapter_status(adapter, stat)                                 \
251     (clear_bit(stat, &(adapter)->status))
252 #define wifi_chg_adapter_status(adapter, stat)                                 \
253     (change_bit(stat, &(adapter)->status))
254 
255 #define DHD_REGISTRATION_TIMEOUT                                               \
256     12000 /* msec : allowed time to finished dhd registration */
257 #define DHD_FW_READY_TIMEOUT                                                   \
258     5000 /* msec : allowed time to finished fw download */
259 
260 typedef struct wifi_adapter_info {
261     const char *name;
262     uint irq_num;
263     uint intr_flags;
264     const char *fw_path;
265     const char *nv_path;
266     const char *clm_path;
267     const char *conf_path;
268     void *wifi_plat_data; /* wifi ctrl func, for backward compatibility */
269     uint bus_type;
270     uint bus_num;
271     uint slot_num;
272     int index;
273     int gpio_wl_reg_on;
274 #ifdef CUSTOMER_OOB
275     int gpio_wl_host_wake;
276 #endif
277     wait_queue_head_t status_event;
278     unsigned long status;
279 #if defined(BT_OVER_SDIO)
280     const char *btfw_path;
281 #endif /* defined (BT_OVER_SDIO) */
282 #if defined(BCMSDIO)
283     struct sdio_func *sdio_func;
284 #endif /* BCMSDIO */
285 #if defined(BCMPCIE)
286     struct pci_dev *pci_dev;
287     struct pci_saved_state *pci_saved_state;
288 #endif /* BCMPCIE */
289 } wifi_adapter_info_t;
290 
291 #define WLAN_PLAT_NODFS_FLAG 0x01
292 #define WLAN_PLAT_AP_FLAG 0x02
293 #if !defined(CONFIG_WIFI_CONTROL_FUNC)
294 struct wifi_platform_data {
295     int (*set_power)(int val, wifi_adapter_info_t *adapter);
296     int (*set_reset)(int val);
297     int (*set_carddetect)(int val);
298 #ifdef BCMDHD_MDRIVER
299     void *(*mem_prealloc)(uint bus_type, int index, int section,
300                           unsigned long size);
301 #else
302     void *(*mem_prealloc)(int section, unsigned long size);
303 #endif
304     int (*get_mac_addr)(unsigned char *buf, int ifidx);
305 #ifdef BCMSDIO
306     int (*get_wake_irq)(void);
307 #endif // endif
308 #ifdef CUSTOM_FORCE_NODFS_FLAG
309     void *(*get_country_code)(char *ccode, u32 flags);
310 #else /* defined (CUSTOM_FORCE_NODFS_FLAG) */
311     void *(*get_country_code)(char *ccode);
312 #endif
313 };
314 #endif
315 
316 typedef struct bcmdhd_wifi_platdata {
317     uint num_adapters;
318     wifi_adapter_info_t *adapters;
319 } bcmdhd_wifi_platdata_t;
320 
321 /** Per STA params. A list of dhd_sta objects are managed in dhd_if */
322 typedef struct dhd_sta {
323     cumm_ctr_t cumm_ctr;    /* cummulative queue length of child flowrings */
324     uint16 flowid[NUMPRIO]; /* allocated flow ring ids (by priority) */
325     void *ifp;              /* associated dhd_if */
326     struct ether_addr ea;   /* stations ethernet mac address */
327     struct list_head list;  /* link into dhd_if::sta_list */
328     int idx;                /* index of self in dhd_pub::sta_pool[] */
329     int ifidx;              /* index of interface in dhd */
330 } dhd_sta_t;
331 typedef dhd_sta_t dhd_sta_pool_t;
332 
333 #ifdef DHD_4WAYM4_FAIL_DISCONNECT
334 typedef enum { M3_RXED, M4_TXFAILED } msg_4way_state_t;
335 #define MAX_4WAY_TIMEOUT_MS 2000
336 #endif /* DHD_4WAYM4_FAIL_DISCONNECT */
337 
338 #ifdef DHD_SEND_HANG_PRIVCMD_ERRORS
339 extern uint32 report_hang_privcmd_err;
340 #endif /* DHD_SEND_HANG_PRIVCMD_ERRORS */
341 
342 #if defined(ARGOS_NOTIFY_CB)
343 int argos_register_notifier_init(struct net_device *net);
344 int argos_register_notifier_deinit(void);
345 
346 extern int sec_argos_register_notifier(struct notifier_block *n, char *label);
347 extern int sec_argos_unregister_notifier(struct notifier_block *n, char *label);
348 
349 typedef struct {
350     struct net_device *wlan_primary_netdev;
351     int argos_rps_cpus_enabled;
352 } argos_rps_ctrl;
353 
354 #define RPS_TPUT_THRESHOLD 300
355 #define DELAY_TO_CLEAR_RPS_CPUS 300
356 #endif // endif
357 
358 #if defined(BT_OVER_SDIO)
359 extern void wl_android_set_wifi_on_flag(bool enable);
360 #endif /* BT_OVER_SDIO */
361 
362 #ifdef DHD_LOG_DUMP
363 /* 0: DLD_BUF_TYPE_GENERAL, 1: DLD_BUF_TYPE_PRESERVE
364  * 2: DLD_BUF_TYPE_SPECIAL
365  */
366 #define DLD_BUFFER_NUM 3
367 
368 #ifndef CUSTOM_LOG_DUMP_BUFSIZE_MB
369 #define CUSTOM_LOG_DUMP_BUFSIZE_MB                                             \
370     4  /* DHD_LOG_DUMP_BUF_SIZE 4 MB static memory in kernel */
371 #endif /* CUSTOM_LOG_DUMP_BUFSIZE_MB */
372 
373 #define LOG_DUMP_TOTAL_BUFSIZE (1024 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
374 
375 /*
376  * Below are different sections that use the prealloced buffer
377  * and sum of the sizes of these should not cross LOG_DUMP_TOTAL_BUFSIZE
378  */
379 #define LOG_DUMP_GENERAL_MAX_BUFSIZE (256 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
380 #define LOG_DUMP_PRESERVE_MAX_BUFSIZE (128 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
381 #define LOG_DUMP_ECNTRS_MAX_BUFSIZE (256 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
382 #define LOG_DUMP_RTT_MAX_BUFSIZE (256 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
383 #define LOG_DUMP_FILTER_MAX_BUFSIZE (128 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
384 
385 #if LOG_DUMP_TOTAL_BUFSIZE <                                                   \
386     (LOG_DUMP_GENERAL_MAX_BUFSIZE + LOG_DUMP_PRESERVE_MAX_BUFSIZE +            \
387      LOG_DUMP_ECNTRS_MAX_BUFSIZE + LOG_DUMP_RTT_MAX_BUFSIZE +                  \
388      LOG_DUMP_FILTER_MAX_BUFSIZE)
389 #error "LOG_DUMP_TOTAL_BUFSIZE is lesser than sum of all rings"
390 #endif // endif
391 
392 /* Special buffer is allocated as separately in prealloc */
393 #define LOG_DUMP_SPECIAL_MAX_BUFSIZE (8 * 1024)
394 
395 #define LOG_DUMP_MAX_FILESIZE (8 * 1024 * 1024) /* 8 MB default */
396 #ifdef CONFIG_LOG_BUF_SHIFT
397 /* 15% of kernel log buf size, if for example klog buf size is 512KB
398  * 15% of 512KB ~= 80KB
399  */
400 #define LOG_DUMP_KERNEL_TAIL_FLUSH_SIZE                                        \
401     (15 * ((1 << CONFIG_LOG_BUF_SHIFT) / 100))
402 #endif /* CONFIG_LOG_BUF_SHIFT */
403 
404 #define LOG_DUMP_COOKIE_BUFSIZE 1024u
405 
406 typedef struct {
407     char *hdr_str;
408     log_dump_section_type_t sec_type;
409 } dld_hdr_t;
410 
411 typedef struct {
412     int attr;
413     char *hdr_str;
414     log_dump_section_type_t sec_type;
415     int log_type;
416 } dld_log_hdr_t;
417 
418 #define DHD_PRINT_BUF_NAME_LEN 30
419 #endif /* DHD_LOG_DUMP */
420 
421 int dhd_wifi_platform_register_drv(void);
422 void dhd_wifi_platform_unregister_drv(void);
423 wifi_adapter_info_t *dhd_wifi_platform_attach_adapter(uint32 bus_type,
424                                                       uint32 bus_num,
425                                                       uint32 slot_num,
426                                                       unsigned long status);
427 wifi_adapter_info_t *
428 dhd_wifi_platform_get_adapter(uint32 bus_type, uint32 bus_num, uint32 slot_num);
429 int wifi_platform_set_power(wifi_adapter_info_t *adapter, bool on,
430                             unsigned long msec);
431 int wifi_platform_bus_enumerate(wifi_adapter_info_t *adapter,
432                                 bool device_present);
433 int wifi_platform_get_irq_number(wifi_adapter_info_t *adapter,
434                                  unsigned long *irq_flags_ptr);
435 int wifi_platform_get_mac_addr(wifi_adapter_info_t *adapter, unsigned char *buf,
436                                int ifidx);
437 #ifdef CUSTOM_COUNTRY_CODE
438 void *wifi_platform_get_country_code(wifi_adapter_info_t *adapter, char *ccode,
439                                      u32 flags);
440 #else
441 void *wifi_platform_get_country_code(wifi_adapter_info_t *adapter, char *ccode);
442 #endif /* CUSTOM_COUNTRY_CODE */
443 void *wifi_platform_prealloc(wifi_adapter_info_t *adapter, int section,
444                              unsigned long size);
445 void *wifi_platform_get_prealloc_func_ptr(wifi_adapter_info_t *adapter);
446 
447 int dhd_get_fw_mode(struct dhd_info *dhdinfo);
448 bool dhd_update_fw_nv_path(struct dhd_info *dhdinfo);
449 
450 #if defined(BT_OVER_SDIO)
451 int dhd_net_bus_get(struct net_device *dev);
452 int dhd_net_bus_put(struct net_device *dev);
453 #endif /* BT_OVER_SDIO */
454 #if defined(WLADPS)
455 #define ADPS_ENABLE 1
456 #define ADPS_DISABLE 0
457 
458 int dhd_enable_adps(dhd_pub_t *dhd, uint8 on);
459 #endif // endif
460 #ifdef DHDTCPSYNC_FLOOD_BLK
461 extern void dhd_reset_tcpsync_info_by_ifp(dhd_if_t *ifp);
462 extern void dhd_reset_tcpsync_info_by_dev(struct net_device *dev);
463 #endif /* DHDTCPSYNC_FLOOD_BLK */
464 
465 int compat_kernel_read(struct file *file, loff_t offset, char *addr,
466                        unsigned long count);
467 int compat_vfs_write(struct file *file, char *addr, int count, loff_t *offset);
468 
469 #endif /* __DHD_LINUX_H__ */
470