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