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