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