diff options
48 files changed, 2849 insertions, 654 deletions
@@ -118,6 +118,8 @@ DHDCFLAGS += -DDHD_COREDUMP # Common feature ################# DHDCFLAGS += -DWL_VIRTUAL_APSTA +DHDCFLAGS += -DDHD_SUPPORT_VFS_CALL +DHDCFLAGS += -DDHD_EXPORT_CNTL_FILE DHDCFLAGS += -DEWP_ECNTRS_LOGGING DHDCFLAGS += -DEWP_RTT_LOGGING @@ -342,6 +344,8 @@ DHDCFLAGS += -DWL_STA_ASSOC_RAND DHDCFLAGS += -DWL_SOFTAP_RAND #p2p MAC randomization DHDCFLAGS += -DWL_P2P_RAND +#Custom Mapping of DSCP to User Priority +DHDCFLAGS += -DWL_CUSTOM_MAPPING_OF_DSCP # Enable below define for production #DHDCFLAGS += -DMACADDR_PROVISION_ENFORCED ifneq ($(CONFIG_BCMDHD_PCIE),) @@ -534,10 +538,6 @@ DHDCFLAGS += -DCUSTOM_PNO_EVENT_LOCK_xTIME=10 DHDCFLAGS += -DMIRACAST_AMPDU_SIZE=8 #Vendor Extension DHDCFLAGS += -DWL_VENDOR_EXT_SUPPORT -#Gscan -DHDCFLAGS += -DGSCAN_SUPPORT -#Background Scan is deprecated -DHDCFLAGS += -DDISABLE_ANDROID_GSCAN #RSSI Monitor DHDCFLAGS += -DRSSI_MONITOR_SUPPORT #RTT @@ -596,6 +596,9 @@ DHDCFLAGS += -DWL_DISABLE_HE_P2P # Advertise HE capabilities DHDCFLAGS += -DWL_CAP_HE +# Advertise OCE_STA capability +DHDCFLAGS += -DWL_CAP_OCE_STA + # Enable RTT LCI/LCR info support DHDCFLAGS += -DWL_RTT_LCI @@ -817,6 +820,7 @@ ifneq ($(CONFIG_SOC_GS101),) DHDCFLAGS += -DDHD_CAP_PLATFORM="\"exynos \"" DHDCFLAGS += -DCONFIG_ARCH_EXYNOS DHDCFLAGS += -DDHD_MODULE_INIT_FORCE_SUCCESS + DHDCFLAGS += -DBCMPCIE_DISABLE_ASYNC_SUSPEND # Dongle init fail DHDCFLAGS += -DPOWERUP_MAX_RETRY=0 # Add chip specific suffix to the output on customer release diff --git a/bcmstdlib_s.c b/bcmstdlib_s.c index 697f4fb..4f7dddd 100644 --- a/bcmstdlib_s.c +++ b/bcmstdlib_s.c @@ -204,7 +204,7 @@ exit: * of course, the buffer size is zero). It does not pad * out the result like strncpy() does. */ -size_t strlcpy(char *dest, const char *src, size_t size) +size_t BCMPOSTTRAPFN(strlcpy)(char *dest, const char *src, size_t size) { size_t i; @@ -95,13 +95,15 @@ BCMRAMFN(privacy_addrmask_get)(void) #ifndef BCM_ARM_BACKTRACE /* function pointers for firmware stack backtrace utility */ -void (*const print_btrace_int_fn)(int depth, uint32 pc, uint32 lr, uint32 sp) = NULL; -void (*const print_btrace_fn)(int depth) = NULL; +void (*const BCMPOST_TRAP_RODATA(print_btrace_int_fn))(int depth, uint32 pc, uint32 lr, uint32 sp) = + NULL; +void (*const BCMPOST_TRAP_RODATA(print_btrace_fn))(int depth) = NULL; #else void print_backtrace(int depth); -void (*const print_btrace_fn)(int depth) = print_backtrace; +void (*const BCMPOST_TRAP_RODATA(print_btrace_fn))(int depth) = print_backtrace; void print_backtrace_int(int depth, uint32 pc, uint32 lr, uint32 sp); -void (*const print_btrace_int_fn)(int depth, uint32 pc, uint32 lr, uint32 sp) = print_backtrace_int; +void (*const BCMPOST_TRAP_RODATA(print_btrace_int_fn))(int depth, uint32 pc, uint32 lr, uint32 sp) = + print_backtrace_int; #endif #if !defined(BCMDONGLEHOST) @@ -535,7 +537,7 @@ BCMFASTPATH(pktfrag_trim_tailbytes)(osl_t * osh, void* p, uint16 trim_len, uint8 /* copy a pkt buffer chain into a buffer */ uint -pktcopy(osl_t *osh, void *p, uint offset, uint len, uchar *buf) +BCMPOSTTRAPFN(pktcopy)(osl_t *osh, void *p, uint offset, uint len, uchar *buf) { uint n, ret = 0; @@ -1180,6 +1182,11 @@ BCMFASTPATH(pktsetprio_qms)(void *pkt, uint8* up_table, bool update_vtag) user_priority = dscp2up(up_table, dscp); PKTSETPRIO(pkt, user_priority); } +#ifdef WL_CUSTOM_MAPPING_OF_DSCP + else { + return pktsetprio(pkt, update_vtag); + } +#endif /* WL_CUSTOM_MAPPING_OF_DSCP */ return (rc | user_priority); } else { @@ -2817,7 +2824,7 @@ bcm_ipv6_ntoa(void *ipv6, char *buf) } #if !defined(BCMROMOFFLOAD_EXCLUDE_BCMUTILS_FUNCS) -const unsigned char bcm_ctype[256] = { +const unsigned char BCMPOST_TRAP_RODATA(bcm_ctype)[256] = { _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */ _BCM_C, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C, @@ -3172,7 +3179,7 @@ bcm_atoipv4(const char *p, struct ipv4_addr *ip) #endif /* !BCMROMOFFLOAD_EXCLUDE_BCMUTILS_FUNCS */ const struct ether_addr ether_bcast = {{255, 255, 255, 255, 255, 255}}; -const struct ether_addr ether_null = {{0, 0, 0, 0, 0, 0}}; +const struct ether_addr BCMPOST_TRAP_RODATA(ether_null) = {{0, 0, 0, 0, 0, 0}}; const struct ether_addr ether_ipv6_mcast = {{0x33, 0x33, 0x00, 0x00, 0x00, 0x01}}; int @@ -47,6 +47,8 @@ #include <linux/proc_fs.h> #include <asm/uaccess.h> #include <asm/unaligned.h> +#include <linux/fs.h> +#include <linux/namei.h> #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) #include <linux/sched/types.h> #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */ @@ -1456,6 +1458,7 @@ typedef struct dhd_pub { #ifdef DHD_SDTC_ETB_DUMP etb_addr_info_t etb_addr_info; uint8 *sdtc_etb_mempool; + uint sdtc_etb_dump_len; bool sdtc_etb_inited; bool collect_sdtc; /* Flag to indicate SDTC dump is required */ #endif /* DHD_SDTC_ETB_DUMP */ @@ -1762,6 +1765,9 @@ typedef struct dhd_pub { #ifdef WL_CFGVENDOR_SEND_ALERT_EVENT uint32 alert_reason; /* reason codes for alert event */ #endif /* WL_CFGVENDOR_SEND_ALERT_EVENT */ +#ifdef DBG_PKT_MON + bool aml_enable; /* aml(assoc mgmt frame logger) enable flags */ +#endif /* DBG_PKT_MON */ } dhd_pub_t; #if defined(__linux__) @@ -4257,6 +4263,7 @@ extern void dhd_sdtc_etb_mempool_deinit(dhd_pub_t *dhd); extern void dhd_sdtc_etb_init(dhd_pub_t *dhd); extern void dhd_sdtc_etb_deinit(dhd_pub_t *dhd); extern void dhd_sdtc_etb_dump(dhd_pub_t *dhd); +extern int dhd_sdtc_etb_hal_file_dump(void *dev, const void *user_buf, uint32 len); #endif /* DHD_SDTC_ETB_DUMP */ #ifdef DHD_TX_PROFILE @@ -4337,4 +4344,162 @@ int dhd_os_send_alert_message(dhd_pub_t *dhdp); bool dhd_validate_chipid(dhd_pub_t *dhdp); #endif /* CUSTOMER_HW4_DEBUG */ +#if defined(__linux__) +#ifdef DHD_SUPPORT_VFS_CALL +static INLINE struct file *dhd_filp_open(const char *filename, int flags, int mode) +{ + return filp_open(filename, flags, mode); +} + +static INLINE int dhd_filp_close(void *image, void *id) +{ + return filp_close((struct file *)image, id); +} + +static INLINE int dhd_i_size_read(const struct inode *inode) +{ + return i_size_read(inode); +} + +static INLINE int dhd_kernel_read_compat(struct file *fp, loff_t pos, void *buf, size_t count) +{ + return kernel_read_compat(fp, pos, buf, count); +} + +static INLINE int dhd_vfs_read(struct file *filep, char *buf, size_t size, loff_t *pos) +{ + return vfs_read(filep, buf, size, pos); +} + +static INLINE int dhd_vfs_write(struct file *filep, char *buf, size_t size, loff_t *pos) +{ + return vfs_write(filep, buf, size, pos); +} + +static INLINE int dhd_vfs_fsync(struct file *filep, int datasync) +{ + return vfs_fsync(filep, datasync); +} + +static INLINE int dhd_vfs_stat(char *buf, struct kstat *stat) +{ + return vfs_stat(buf, stat); +} + +static INLINE int dhd_kern_path(char *name, int flags, struct path *file_path) +{ + return kern_path(name, flags, file_path); +} +#else +static INLINE struct file *dhd_filp_open(const char *filename, int flags, int mode) + { return NULL; } +static INLINE int dhd_filp_close(void *image, void *id) + { return 0; } +static INLINE int dhd_i_size_read(const struct inode *inode) + { return 0; } +static INLINE int dhd_kernel_read_compat(struct file *fp, loff_t pos, void *buf, size_t count) + { return 0; } +static INLINE int dhd_vfs_read(struct file *filep, char *buf, size_t size, loff_t *pos) + { return 0; } +static INLINE int dhd_vfs_write(struct file *filep, char *buf, size_t size, loff_t *pos) + { return 0; } +static INLINE int dhd_vfs_fsync(struct file *filep, int datasync) + { return 0; } +static INLINE int dhd_vfs_stat(char *buf, struct kstat *stat) + { return 0; } +static INLINE int dhd_kern_path(char *name, int flags, struct path *file_path) + { return 0; } +#endif /* DHD_SUPPORT_VFS_CALL */ +#endif /* __linux__ */ + +#ifdef DHD_LOG_DUMP +extern char *dhd_log_dump_get_timestamp(void); +#ifdef DHD_EFI +/* FW verbose/console output to FW ring buffer */ +extern void dhd_log_dump_print(const char *fmt, ...); +/* DHD verbose/console output to DHD ring buffer */ +extern void dhd_log_dump_print_drv(const char *fmt, ...); +#define DHD_LOG_DUMP_WRITE(fmt, ...) dhd_log_dump_print_drv(fmt, ##__VA_ARGS__) +#define DHD_LOG_DUMP_WRITE_FW(fmt, ...) dhd_log_dump_print(fmt, ##__VA_ARGS__) +#else +#ifndef _DHD_LOG_DUMP_DEFINITIONS_ +#define _DHD_LOG_DUMP_DEFINITIONS_ +#define GENERAL_LOG_HDR "\n-------------------- General log ---------------------------\n" +#define PRESERVE_LOG_HDR "\n-------------------- Preserve log ---------------------------\n" +#define SPECIAL_LOG_HDR "\n-------------------- Special log ---------------------------\n" +#define DHD_DUMP_LOG_HDR "\n-------------------- 'dhd dump' log -----------------------\n" +#define EXT_TRAP_LOG_HDR "\n-------------------- Extended trap data -------------------\n" +#define HEALTH_CHK_LOG_HDR "\n-------------------- Health check data --------------------\n" +#ifdef DHD_DUMP_PCIE_RINGS +#define FLOWRING_DUMP_HDR "\n-------------------- Flowring dump --------------------\n" +#endif /* DHD_DUMP_PCIE_RINGS */ +#define DHD_LOG_DUMP_DLD(fmt, ...) \ + dhd_log_dump_write(DLD_BUF_TYPE_GENERAL, NULL, 0, fmt, ##__VA_ARGS__) +#define DHD_LOG_DUMP_DLD_EX(fmt, ...) \ + dhd_log_dump_write(DLD_BUF_TYPE_SPECIAL, NULL, 0, fmt, ##__VA_ARGS__) +#define DHD_LOG_DUMP_DLD_PRSRV(fmt, ...) \ + dhd_log_dump_write(DLD_BUF_TYPE_PRESERVE, NULL, 0, fmt, ##__VA_ARGS__) +#endif /* !_DHD_LOG_DUMP_DEFINITIONS_ */ + +#ifndef DHD_LOG_DUMP_RING_DEFINITIONS +#define DHD_LOG_DUMP_RING_DEFINITIONS +#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING +/* Enabled DHD_DEBUGABILITY_LOG_DUMP_RING */ +extern void dhd_dbg_ring_write(int type, char *binary_data, + int binary_len, const char *fmt, ...); +extern char* dhd_dbg_get_system_timestamp(void); +#define DHD_DBG_RING(fmt, ...) \ + dhd_dbg_ring_write(DRIVER_LOG_RING_ID, NULL, 0, fmt, ##__VA_ARGS__) +#define DHD_DBG_RING_EX(fmt, ...) \ + dhd_dbg_ring_write(FW_VERBOSE_RING_ID, NULL, 0, fmt, ##__VA_ARGS__) +#define DHD_DBG_RING_ROAM(fmt, ...) \ + dhd_dbg_ring_write(ROAM_STATS_RING_ID, NULL, 0, fmt, ##__VA_ARGS__) + +#define DHD_LOG_DUMP_WRITE DHD_DBG_RING +#define DHD_LOG_DUMP_WRITE_EX DHD_DBG_RING_EX +#define DHD_LOG_DUMP_WRITE_PRSRV DHD_DBG_RING +#define DHD_LOG_DUMP_WRITE_ROAM DHD_DBG_RING_ROAM + +#define DHD_PREFIX_TS "[%s][%s] ", \ + dhd_dbg_get_system_timestamp(), dhd_log_dump_get_timestamp() +#define DHD_PREFIX_TS_FN "[%s][%s] %s: ", \ + dhd_dbg_get_system_timestamp(), dhd_log_dump_get_timestamp(), __func__ +#define DHD_LOG_DUMP_WRITE_TS DHD_DBG_RING(DHD_PREFIX_TS) +#define DHD_LOG_DUMP_WRITE_TS_FN DHD_DBG_RING(DHD_PREFIX_TS_FN) +#define DHD_LOG_DUMP_WRITE_EX_TS DHD_DBG_RING_EX(DHD_PREFIX_TS) +#define DHD_LOG_DUMP_WRITE_EX_TS_FN DHD_DBG_RING_EX(DHD_PREFIX_TS_FN) +#define DHD_LOG_DUMP_WRITE_PRSRV_TS DHD_DBG_RING(DHD_PREFIX_TS) +#define DHD_LOG_DUMP_WRITE_PRSRV_TS_FN DHD_DBG_RING(DHD_PREFIX_TS_FN) +#define DHD_LOG_DUMP_WRITE_ROAM_TS DHD_DBG_RING_ROAM(DHD_PREFIX_TS) +#define DHD_LOG_DUMP_WRITE_ROAM_TS_FN DHD_DBG_RING_ROAM(DHD_PREFIX_TS_FN) +#else +/* Not enabled DHD_DEBUGABILITY_LOG_DUMP_RING */ +#define DHD_LOG_DUMP_WRITE DHD_LOG_DUMP_DLD +#define DHD_LOG_DUMP_WRITE_EX DHD_LOG_DUMP_DLD_EX +#define DHD_LOG_DUMP_WRITE_PRSRV DHD_LOG_DUMP_DLD_PRSRV +#define DHD_LOG_DUMP_WRITE_ROAM DHD_LOG_DUMP_DLD + +#define DHD_PREFIX_TS "[%s]: ", dhd_log_dump_get_timestamp() +#define DHD_PREFIX_TS_FN "[%s] %s: ", dhd_log_dump_get_timestamp(), __func__ +#define DHD_LOG_DUMP_WRITE_TS DHD_LOG_DUMP_DLD(DHD_PREFIX_TS) +#define DHD_LOG_DUMP_WRITE_TS_FN DHD_LOG_DUMP_DLD(DHD_PREFIX_TS_FN) +#define DHD_LOG_DUMP_WRITE_EX_TS DHD_LOG_DUMP_DLD_EX(DHD_PREFIX_TS) +#define DHD_LOG_DUMP_WRITE_EX_TS_FN DHD_LOG_DUMP_DLD_EX(DHD_PREFIX_TS_FN) +#define DHD_LOG_DUMP_WRITE_PRSRV_TS DHD_LOG_DUMP_DLD_PRSRV(DHD_PREFIX_TS) +#define DHD_LOG_DUMP_WRITE_PRSRV_TS_FN DHD_LOG_DUMP_DLD_PRSRV(DHD_PREFIX_TS_FN) +#define DHD_LOG_DUMP_WRITE_ROAM_TS DHD_LOG_DUMP_DLD(DHD_PREFIX_TS) +#define DHD_LOG_DUMP_WRITE_ROAM_TS_FN DHD_LOG_DUMP_DLD(DHD_PREFIX_TS_FN) +#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */ +#endif /* DHD_LOG_DUMP_RING_DEFINITIONS */ + +#endif /* DHD_EFI */ +#define CONCISE_DUMP_BUFLEN 32 * 1024 +#define ECNTRS_LOG_HDR "\n-------------------- Ecounters log --------------------------\n" +#ifdef DHD_STATUS_LOGGING +#define STATUS_LOG_HDR "\n-------------------- Status log -----------------------\n" +#endif /* DHD_STATUS_LOGGING */ +#define RTT_LOG_HDR "\n-------------------- RTT log --------------------------\n" +#define BCM_TRACE_LOG_HDR "\n-------------------- BCM Trace log --------------------------\n" +#define COOKIE_LOG_HDR "\n-------------------- Cookie List ----------------------------\n" +#endif /* DHD_LOG_DUMP */ #endif /* _dhd_h_ */ diff --git a/dhd_common.c b/dhd_common.c index 0e95a1e..02407ac 100644 --- a/dhd_common.c +++ b/dhd_common.c @@ -1249,11 +1249,13 @@ void dhd_sdtc_etb_deinit(dhd_pub_t *dhd) { dhd->sdtc_etb_inited = FALSE; + dhd->sdtc_etb_dump_len = 0; } int dhd_sdtc_etb_mempool_init(dhd_pub_t *dhd) { + dhd->sdtc_etb_dump_len = 0; dhd->sdtc_etb_mempool = (uint8 *) MALLOCZ(dhd->osh, DHD_SDTC_ETB_MEMPOOL_SIZE); if (dhd->sdtc_etb_mempool == NULL) { DHD_ERROR(("%s: MALLOC of sdtc_etb_mempool failed\n", @@ -4198,12 +4200,17 @@ wl_show_host_event(dhd_pub_t *dhd_pub, wl_event_msg_t *event, void *event_data, break; #ifdef WL_CLIENT_SAE - case WLC_E_AUTH_START: - DHD_EVENT(("MACEVENT: %s, MAC %s, reason %d\n", event_name, - eabuf, (int)reason)); - break; + case WLC_E_AUTH_START: + DHD_EVENT(("MACEVENT: %s, MAC %s, reason %d\n", event_name, + eabuf, (int)reason)); + break; #endif /* WL_CLIENT_SAE */ + case WLC_E_BSSID: + DHD_EVENT(("MACEVENT: %s, MAC %s, reason %d datalen %d\n", event_name, + eabuf, (int)reason, datalen)); + break; + case WLC_E_ASSOC: case WLC_E_REASSOC: if (status == WLC_E_STATUS_SUCCESS) { @@ -30,95 +30,6 @@ #include "wl_nddbg.h" #endif /* defined(NDIS) */ -#ifdef DHD_LOG_DUMP -extern char *dhd_log_dump_get_timestamp(void); -#ifdef DHD_EFI -/* FW verbose/console output to FW ring buffer */ -extern void dhd_log_dump_print(const char *fmt, ...); -/* DHD verbose/console output to DHD ring buffer */ -extern void dhd_log_dump_print_drv(const char *fmt, ...); -#define DHD_LOG_DUMP_WRITE(fmt, ...) dhd_log_dump_print_drv(fmt, ##__VA_ARGS__) -#define DHD_LOG_DUMP_WRITE_FW(fmt, ...) dhd_log_dump_print(fmt, ##__VA_ARGS__) -#else -#ifndef _DHD_LOG_DUMP_DEFINITIONS_ -#define _DHD_LOG_DUMP_DEFINITIONS_ -#define GENERAL_LOG_HDR "\n-------------------- General log ---------------------------\n" -#define PRESERVE_LOG_HDR "\n-------------------- Preserve log ---------------------------\n" -#define SPECIAL_LOG_HDR "\n-------------------- Special log ---------------------------\n" -#define DHD_DUMP_LOG_HDR "\n-------------------- 'dhd dump' log -----------------------\n" -#define EXT_TRAP_LOG_HDR "\n-------------------- Extended trap data -------------------\n" -#define HEALTH_CHK_LOG_HDR "\n-------------------- Health check data --------------------\n" -#ifdef DHD_DUMP_PCIE_RINGS -#define FLOWRING_DUMP_HDR "\n-------------------- Flowring dump --------------------\n" -#endif /* DHD_DUMP_PCIE_RINGS */ -#define DHD_LOG_DUMP_DLD(fmt, ...) \ - dhd_log_dump_write(DLD_BUF_TYPE_GENERAL, NULL, 0, fmt, ##__VA_ARGS__) -#define DHD_LOG_DUMP_DLD_EX(fmt, ...) \ - dhd_log_dump_write(DLD_BUF_TYPE_SPECIAL, NULL, 0, fmt, ##__VA_ARGS__) -#define DHD_LOG_DUMP_DLD_PRSRV(fmt, ...) \ - dhd_log_dump_write(DLD_BUF_TYPE_PRESERVE, NULL, 0, fmt, ##__VA_ARGS__) -#endif /* !_DHD_LOG_DUMP_DEFINITIONS_ */ - -#ifndef DHD_LOG_DUMP_RING_DEFINITIONS -#define DHD_LOG_DUMP_RING_DEFINITIONS -#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING -/* Enabled DHD_DEBUGABILITY_LOG_DUMP_RING */ -extern void dhd_dbg_ring_write(int type, char *binary_data, - int binary_len, const char *fmt, ...); -extern char* dhd_dbg_get_system_timestamp(void); -#define DHD_DBG_RING(fmt, ...) \ - dhd_dbg_ring_write(DRIVER_LOG_RING_ID, NULL, 0, fmt, ##__VA_ARGS__) -#define DHD_DBG_RING_EX(fmt, ...) \ - dhd_dbg_ring_write(FW_VERBOSE_RING_ID, NULL, 0, fmt, ##__VA_ARGS__) -#define DHD_DBG_RING_ROAM(fmt, ...) \ - dhd_dbg_ring_write(ROAM_STATS_RING_ID, NULL, 0, fmt, ##__VA_ARGS__) - -#define DHD_LOG_DUMP_WRITE DHD_DBG_RING -#define DHD_LOG_DUMP_WRITE_EX DHD_DBG_RING_EX -#define DHD_LOG_DUMP_WRITE_PRSRV DHD_DBG_RING -#define DHD_LOG_DUMP_WRITE_ROAM DHD_DBG_RING_ROAM - -#define DHD_PREFIX_TS "[%s][%s]: ", dhd_dbg_get_system_timestamp(), dhd_log_dump_get_timestamp() -#define DHD_PREFIX_TS_FN DHD_PREFIX_TS -#define DHD_LOG_DUMP_WRITE_TS DHD_DBG_RING(DHD_PREFIX_TS) -#define DHD_LOG_DUMP_WRITE_TS_FN DHD_DBG_RING(DHD_PREFIX_TS_FN) -#define DHD_LOG_DUMP_WRITE_EX_TS DHD_DBG_RING_EX(DHD_PREFIX_TS) -#define DHD_LOG_DUMP_WRITE_EX_TS_FN DHD_DBG_RING_EX(DHD_PREFIX_TS_FN) -#define DHD_LOG_DUMP_WRITE_PRSRV_TS DHD_DBG_RING(DHD_PREFIX_TS) -#define DHD_LOG_DUMP_WRITE_PRSRV_TS_FN DHD_DBG_RING(DHD_PREFIX_TS_FN) -#define DHD_LOG_DUMP_WRITE_ROAM_TS DHD_DBG_RING_ROAM(DHD_PREFIX_TS) -#define DHD_LOG_DUMP_WRITE_ROAM_TS_FN DHD_DBG_RING_ROAM(DHD_PREFIX_TS_FN) -#else -/* Not enabled DHD_DEBUGABILITY_LOG_DUMP_RING */ -#define DHD_LOG_DUMP_WRITE DHD_LOG_DUMP_DLD -#define DHD_LOG_DUMP_WRITE_EX DHD_LOG_DUMP_DLD_EX -#define DHD_LOG_DUMP_WRITE_PRSRV DHD_LOG_DUMP_DLD_PRSRV -#define DHD_LOG_DUMP_WRITE_ROAM DHD_LOG_DUMP_DLD - -#define DHD_PREFIX_TS "[%s]: ", dhd_log_dump_get_timestamp() -#define DHD_PREFIX_TS_FN "[%s] %s: ", dhd_log_dump_get_timestamp(), __func__ -#define DHD_LOG_DUMP_WRITE_TS DHD_LOG_DUMP_DLD(DHD_PREFIX_TS) -#define DHD_LOG_DUMP_WRITE_TS_FN DHD_LOG_DUMP_DLD(DHD_PREFIX_TS_FN) -#define DHD_LOG_DUMP_WRITE_EX_TS DHD_LOG_DUMP_DLD_EX(DHD_PREFIX_TS) -#define DHD_LOG_DUMP_WRITE_EX_TS_FN DHD_LOG_DUMP_DLD_EX(DHD_PREFIX_TS_FN) -#define DHD_LOG_DUMP_WRITE_PRSRV_TS DHD_LOG_DUMP_DLD_PRSRV(DHD_PREFIX_TS) -#define DHD_LOG_DUMP_WRITE_PRSRV_TS_FN DHD_LOG_DUMP_DLD_PRSRV(DHD_PREFIX_TS_FN) -#define DHD_LOG_DUMP_WRITE_ROAM_TS DHD_LOG_DUMP_DLD(DHD_PREFIX_TS) -#define DHD_LOG_DUMP_WRITE_ROAM_TS_FN DHD_LOG_DUMP_DLD(DHD_PREFIX_TS_FN) -#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */ -#endif /* DHD_LOG_DUMP_RING_DEFINITIONS */ - -#endif /* DHD_EFI */ -#define CONCISE_DUMP_BUFLEN 32 * 1024 -#define ECNTRS_LOG_HDR "\n-------------------- Ecounters log --------------------------\n" -#ifdef DHD_STATUS_LOGGING -#define STATUS_LOG_HDR "\n-------------------- Status log -----------------------\n" -#endif /* DHD_STATUS_LOGGING */ -#define RTT_LOG_HDR "\n-------------------- RTT log --------------------------\n" -#define BCM_TRACE_LOG_HDR "\n-------------------- BCM Trace log --------------------------\n" -#define COOKIE_LOG_HDR "\n-------------------- Cookie List ----------------------------\n" -#endif /* DHD_LOG_DUMP */ - #ifdef DHD_DEBUGABILITY_LOG_DUMP_RING /* Only for writing to ring */ #define DHD_INFO_RING(args) DHD_ERROR(args) @@ -286,6 +197,7 @@ do { \ #define DHD_LOG_MEM(args) \ do { \ if (dhd_msg_level & DHD_ERROR_VAL) { \ + DHD_LOG_DUMP_WRITE_TS; \ DHD_LOG_DUMP_WRITE args; \ } \ } while (0) @@ -366,6 +278,15 @@ do { \ DHD_LOG_DUMP_WRITE_ROAM args; \ } \ } while (0) + +#define DHD_PKT_MON(args) \ +do { \ + if (dhd_msg_level & DHD_PKT_MON_VAL) { \ + DBG_PRINT_SYSTEM_TIME; \ + pr_cont args; \ + } \ +} while (0) + #endif /* DHD_EFI */ #else /* DHD_LOG_DUMP */ /* !DHD_LOG_DUMP */ @@ -378,6 +299,7 @@ do { \ #define DHD_PRSRV_MEM(args) DHD_EVENT(args) #define DHD_ERROR_EX(args) DHD_ERROR(args) #define DHD_ERROR_ROAM(args) DHD_ERROR(args) +#define DHD_PKT_MON(args) DHD_ERROR(args) #endif /* DHD_LOG_DUMP */ #define DHD_DATA(args) do {if (dhd_msg_level & DHD_DATA_VAL) printf args;} while (0) @@ -393,7 +315,6 @@ do { \ #define DHD_REORDER(args) do {if (dhd_msg_level & DHD_REORDER_VAL) printf args;} while (0) #define DHD_PNO(args) do {if (dhd_msg_level & DHD_PNO_VAL) printf args;} while (0) #define DHD_RTT(args) do {if (dhd_msg_level & DHD_RTT_VAL) printf args;} while (0) -#define DHD_PKT_MON(args) do {if (dhd_msg_level & DHD_PKT_MON_VAL) printf args;} while (0) #if defined(DHD_LOG_DUMP) #if defined(DHD_EFI) @@ -415,6 +336,7 @@ do { \ printf args; \ } \ if (dhd_log_level & DHD_FWLOG_VAL) { \ + DHD_LOG_DUMP_WRITE_EX_TS; \ DHD_LOG_DUMP_FWLOG args; \ } \ } while (0) diff --git a/dhd_debug.c b/dhd_debug.c index da54309..952fc6f 100644 --- a/dhd_debug.c +++ b/dhd_debug.c @@ -38,6 +38,10 @@ #include <event_log.h> #include <event_trace.h> #include <msgtrace.h> +#if defined(DBG_PKT_MON) +#include <dhd_linux_priv.h> +#include <dhd_linux_wq.h> +#endif /* DBG_PKT_MON */ #if defined(DHD_EVENT_LOG_FILTER) #include <dhd_event_log_filter.h> @@ -1496,6 +1500,83 @@ __dhd_dbg_map_tx_status_to_pkt_fate(uint16 status) #endif /* DBG_PKT_MON || DHD_PKT_LOGGING */ #ifdef DBG_PKT_MON +static int do_iovar_aml_enable(dhd_pub_t *dhdp, uint val); +static void dhd_do_aml_disable(void *handle, void *event_info, u8 event); +void dhd_schedule_aml_disable(dhd_pub_t *dhdp); + +static int +do_iovar_aml_enable(dhd_pub_t *dhdp, uint val) +{ + wl_aml_iovar_t *iov_in; + wl_aml_iov_uint_data_t *subcmd; + int buf_size, alloc_len, ret = BCME_OK; + + buf_size = OFFSETOF(wl_aml_iovar_t, data); + alloc_len = buf_size + sizeof(wl_aml_iov_uint_data_t); + + iov_in = MALLOCZ(dhdp->osh, alloc_len); + if (!iov_in) { + DHD_ERROR(("%s: Error allocating %u bytes for aml enable\n", + __FUNCTION__, alloc_len)); + return BCME_NOMEM; + } + + iov_in->hdr.ver = htod16(WL_AML_IOV_VERSION); + iov_in->hdr.len = htod16(alloc_len); + iov_in->hdr.subcmd = htod16(WL_AML_SUBCMD_ENABLE); + + if (val & ~(1u << WL_AML_ASSOC_ENABLE | 1u << WL_AML_ROAM_ENABLE)) { + ret = BCME_BADARG; + goto fail; + } + + subcmd = (wl_aml_iov_uint_data_t *)iov_in->data; + subcmd->val = htod32(val); + + ret = dhd_iovar(dhdp, 0, "aml", (char *)iov_in, alloc_len, NULL, 0, TRUE); + if (ret < 0) { + DHD_ERROR(("%s aml failed %d\n", __FUNCTION__, ret)); + ret = BCME_ERROR; + goto fail; + } + +fail: + if (iov_in) { + MFREE(dhdp->osh, iov_in, alloc_len); + } + + return ret; +} + +static void dhd_do_aml_disable(void *handle, void *event_info, u8 event) +{ + dhd_info_t *dhd = (dhd_info_t *)handle; + dhd_pub_t *dhdp = NULL; + uint val = 0; /* Disabled */ + + dhdp = &dhd->pub; + if (!dhdp) { + DHD_ERROR(("%s: dhdp is NULL\n", __FUNCTION__)); + return; + } + + if (do_iovar_aml_enable(dhdp, val) == BCME_OK) { + dhdp->aml_enable = FALSE; + } + + return; +} + +void dhd_schedule_aml_disable(dhd_pub_t *dhdp) +{ + if (dhdp->dbg->pkt_mon.tx_pkt_state == PKT_MON_STOPPED && + dhdp->dbg->pkt_mon.rx_pkt_state == PKT_MON_STOPPED) { + DHD_ERROR(("%s: scheduling aml iovar..\n", __FUNCTION__)); + dhd_deferred_schedule_work(dhdp->info->dhd_deferred_wq, NULL, + DHD_WQ_WORK_AML_IOVAR, dhd_do_aml_disable, DHD_WQ_WORK_PRIORITY_HIGH); + } +} + static int __dhd_dbg_free_tx_pkts(dhd_pub_t *dhdp, dhd_dbg_tx_info_t *tx_pkts, uint16 pkt_count) @@ -1714,6 +1795,10 @@ dhd_dbg_start_pkt_monitor(dhd_pub_t *dhdp) return -EINVAL; } + if (do_iovar_aml_enable(dhdp, 1) == BCME_OK) { + dhdp->aml_enable = TRUE; + } + DHD_PKT_MON_LOCK(dhdp->dbg->pkt_mon_lock, flags); tx_pkt_state = dhdp->dbg->pkt_mon.tx_pkt_state; tx_status_state = dhdp->dbg->pkt_mon.tx_status_state; @@ -1765,7 +1850,7 @@ dhd_dbg_start_pkt_monitor(dhd_pub_t *dhdp) } int -dhd_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid) +dhd_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid, frame_type type, uint8 mgmt_acked) { dhd_dbg_tx_report_t *tx_report; dhd_dbg_tx_info_t *tx_pkts; @@ -1791,19 +1876,35 @@ dhd_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid) pkt_hash = __dhd_dbg_pkt_hash((uintptr_t)pkt, pktid); driver_ts = __dhd_dbg_driver_ts_usec(); - tx_pkts[pkt_pos].info.pkt = PKTDUP(dhdp->osh, pkt); + if (type == FRAME_TYPE_80211_MGMT) { + tx_pkts[pkt_pos].info.pkt = pkt; + if (mgmt_acked) { + tx_pkts[pkt_pos].fate = TX_PKT_FATE_ACKED; + } else { + tx_pkts[pkt_pos].fate = TX_PKT_FATE_SENT; + } + } else { + tx_pkts[pkt_pos].info.pkt = PKTDUP(dhdp->osh, pkt); + tx_pkts[pkt_pos].fate = TX_PKT_FATE_DRV_QUEUED; + } + tx_pkts[pkt_pos].info.pkt_len = PKTLEN(dhdp->osh, pkt); tx_pkts[pkt_pos].info.pkt_hash = pkt_hash; tx_pkts[pkt_pos].info.driver_ts = driver_ts; tx_pkts[pkt_pos].info.firmware_ts = 0U; - tx_pkts[pkt_pos].info.payload_type = FRAME_TYPE_ETHERNET_II; - tx_pkts[pkt_pos].fate = TX_PKT_FATE_DRV_QUEUED; + tx_pkts[pkt_pos].info.payload_type = type; tx_report->pkt_pos++; } else { + if (type == FRAME_TYPE_80211_MGMT) { + PKTFREE(dhdp->osh, pkt, TRUE); + } dhdp->dbg->pkt_mon.tx_pkt_state = PKT_MON_STOPPED; DHD_PKT_MON(("%s(): tx pkt logging stopped, reached " "max limit\n", __FUNCTION__)); + if (dhdp->aml_enable) { + dhd_schedule_aml_disable(dhdp); + } } } @@ -1892,7 +1993,7 @@ dhd_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt, uint32 pktid, } int -dhd_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt) +dhd_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt, frame_type type) { dhd_dbg_rx_report_t *rx_report; dhd_dbg_rx_info_t *rx_pkts; @@ -1917,19 +2018,29 @@ dhd_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt) rx_pkts = rx_report->rx_pkts; driver_ts = __dhd_dbg_driver_ts_usec(); - rx_pkts[pkt_pos].info.pkt = PKTDUP(dhdp->osh, pkt); + if (type == FRAME_TYPE_80211_MGMT) { + rx_pkts[pkt_pos].info.pkt = pkt; + } else { + rx_pkts[pkt_pos].info.pkt = PKTDUP(dhdp->osh, pkt); + } rx_pkts[pkt_pos].info.pkt_len = PKTLEN(dhdp->osh, pkt); rx_pkts[pkt_pos].info.pkt_hash = 0U; rx_pkts[pkt_pos].info.driver_ts = driver_ts; rx_pkts[pkt_pos].info.firmware_ts = 0U; - rx_pkts[pkt_pos].info.payload_type = FRAME_TYPE_ETHERNET_II; + rx_pkts[pkt_pos].info.payload_type = type; rx_pkts[pkt_pos].fate = RX_PKT_FATE_SUCCESS; rx_report->pkt_pos++; } else { + if (type == FRAME_TYPE_80211_MGMT) { + PKTFREE(dhdp->osh, pkt, TRUE); + } dhdp->dbg->pkt_mon.rx_pkt_state = PKT_MON_STOPPED; DHD_PKT_MON(("%s(): rx pkt logging stopped, reached " "max limit\n", __FUNCTION__)); + if (dhdp->aml_enable) { + dhd_schedule_aml_disable(dhdp); + } } } @@ -2072,7 +2183,7 @@ dhd_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp, void __user *user_buf, if (!pkt_count) { DHD_ERROR(("%s(): no tx_status in tx completion messages, " "make sure that 'd11status' is enabled in firmware, " - "status_pos=%u", __FUNCTION__, pkt_count)); + "status_pos=%u\n", __FUNCTION__, pkt_count)); } return BCME_OK; diff --git a/dhd_debug.h b/dhd_debug.h index c198afc..3937c14 100644 --- a/dhd_debug.h +++ b/dhd_debug.h @@ -635,10 +635,11 @@ typedef struct dhd_dbg_rx_report typedef void (*dbg_pullreq_t)(void *os_priv, const int ring_id); typedef void (*dbg_urgent_noti_t) (dhd_pub_t *dhdp, const void *data, const uint32 len); -typedef int (*dbg_mon_tx_pkts_t) (dhd_pub_t *dhdp, void *pkt, uint32 pktid); +typedef int (*dbg_mon_tx_pkts_t) (dhd_pub_t *dhdp, void *pkt, uint32 pktid, + frame_type type, uint8 mgmt_acked); typedef int (*dbg_mon_tx_status_t) (dhd_pub_t *dhdp, void *pkt, uint32 pktid, uint16 status); -typedef int (*dbg_mon_rx_pkts_t) (dhd_pub_t *dhdp, void *pkt); +typedef int (*dbg_mon_rx_pkts_t) (dhd_pub_t *dhdp, void *pkt, frame_type type); typedef struct dhd_dbg_pkt_mon { @@ -678,10 +679,11 @@ typedef struct dhd_dbg { (((status_count) >= (pkt_count)) || ((status_count) >= MAX_FATE_LOG_LEN)) #ifdef DBG_PKT_MON -#define DHD_DBG_PKT_MON_TX(dhdp, pkt, pktid) \ +#define DHD_DBG_PKT_MON_TX(dhdp, pkt, pktid, type, mgmt_acked) \ do { \ if ((dhdp) && (dhdp)->dbg && (dhdp)->dbg->pkt_mon.tx_pkt_mon && (pkt)) { \ - (dhdp)->dbg->pkt_mon.tx_pkt_mon((dhdp), (pkt), (pktid)); \ + (dhdp)->dbg->pkt_mon.tx_pkt_mon((dhdp), (pkt), \ + (pktid), (type), (mgmt_acked)); \ } \ } while (0); #define DHD_DBG_PKT_MON_TX_STATUS(dhdp, pkt, pktid, status) \ @@ -690,11 +692,11 @@ typedef struct dhd_dbg { (dhdp)->dbg->pkt_mon.tx_status_mon((dhdp), (pkt), (pktid), (status)); \ } \ } while (0); -#define DHD_DBG_PKT_MON_RX(dhdp, pkt) \ +#define DHD_DBG_PKT_MON_RX(dhdp, pkt, type) \ do { \ if ((dhdp) && (dhdp)->dbg && (dhdp)->dbg->pkt_mon.rx_pkt_mon && (pkt)) { \ if (ntoh16((pkt)->protocol) != ETHER_TYPE_BRCM) { \ - (dhdp)->dbg->pkt_mon.rx_pkt_mon((dhdp), (pkt)); \ + (dhdp)->dbg->pkt_mon.rx_pkt_mon((dhdp), (pkt), (type)); \ } \ } \ } while (0); @@ -704,9 +706,9 @@ typedef struct dhd_dbg { #define DHD_DBG_PKT_MON_STOP(dhdp) \ dhd_os_dbg_stop_pkt_monitor((dhdp)); #else -#define DHD_DBG_PKT_MON_TX(dhdp, pkt, pktid) +#define DHD_DBG_PKT_MON_TX(dhdp, pkt, pktid, type, mgmt_acked) #define DHD_DBG_PKT_MON_TX_STATUS(dhdp, pkt, pktid, status) -#define DHD_DBG_PKT_MON_RX(dhdp, pkt) +#define DHD_DBG_PKT_MON_RX(dhdp, pkt, type) #define DHD_DBG_PKT_MON_START(dhdp) #define DHD_DBG_PKT_MON_STOP(dhdp) #endif /* DBG_PKT_MON */ @@ -812,10 +814,11 @@ extern int dhd_dbg_attach_pkt_monitor(dhd_pub_t *dhdp, dbg_mon_tx_status_t tx_status_mon, dbg_mon_rx_pkts_t rx_pkt_mon); extern int dhd_dbg_start_pkt_monitor(dhd_pub_t *dhdp); -extern int dhd_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid); +extern int dhd_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, + uint32 pktid, frame_type type, uint8 mgmt_acked); extern int dhd_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt, uint32 pktid, uint16 status); -extern int dhd_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt); +extern int dhd_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt, frame_type type); extern int dhd_dbg_stop_pkt_monitor(dhd_pub_t *dhdp); extern int dhd_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp, void __user *user_buf, uint16 req_count, uint16 *resp_count); @@ -851,10 +854,11 @@ extern int dhd_os_dbg_get_feature(dhd_pub_t *dhdp, int32 *features); extern int dhd_os_dbg_attach_pkt_monitor(dhd_pub_t *dhdp); extern int dhd_os_dbg_start_pkt_monitor(dhd_pub_t *dhdp); extern int dhd_os_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, - uint32 pktid); + uint32 pktid, frame_type type, uint8 mgmt_acked); extern int dhd_os_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt, uint32 pktid, uint16 status); -extern int dhd_os_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt); +extern int dhd_os_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt, + frame_type type); extern int dhd_os_dbg_stop_pkt_monitor(dhd_pub_t *dhdp); extern int dhd_os_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp, void __user *user_buf, uint16 req_count, uint16 *resp_count); diff --git a/dhd_debug_linux.c b/dhd_debug_linux.c index d8862fa..9a6bbd3 100644 --- a/dhd_debug_linux.c +++ b/dhd_debug_linux.c @@ -388,9 +388,10 @@ dhd_os_dbg_start_pkt_monitor(dhd_pub_t *dhdp) } int -dhd_os_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid) +dhd_os_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid, + frame_type type, uint8 mgmt_acked) { - return dhd_dbg_monitor_tx_pkts(dhdp, pkt, pktid); + return dhd_dbg_monitor_tx_pkts(dhdp, pkt, pktid, type, mgmt_acked); } int @@ -401,9 +402,9 @@ dhd_os_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt, uint32 pktid, } int -dhd_os_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt) +dhd_os_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt, frame_type type) { - return dhd_dbg_monitor_rx_pkts(dhdp, pkt); + return dhd_dbg_monitor_rx_pkts(dhdp, pkt, type); } int diff --git a/dhd_flowring.c b/dhd_flowring.c index 4a1b215..f28d86f 100644 --- a/dhd_flowring.c +++ b/dhd_flowring.c @@ -1212,7 +1212,7 @@ dhd_flow_rings_delete_for_peer(dhd_pub_t *dhdp, uint8 ifindex, char *addr) uint32 id; flow_ring_table_t *flow_ring_table; - DHD_ERROR(("%s: ifindex %u\n", __FUNCTION__, ifindex)); + DHD_INFO(("%s: ifindex %u\n", __FUNCTION__, ifindex)); ASSERT(ifindex < DHD_MAX_IFS); if (ifindex >= DHD_MAX_IFS) @@ -1237,7 +1237,7 @@ dhd_flow_rings_delete_for_peer(dhd_pub_t *dhdp, uint8 ifindex, char *addr) (!memcmp(flow_ring_table[id].flow_info.da, addr, ETHER_ADDR_LEN)) && ((flow_ring_table[id].status == FLOW_RING_STATUS_OPEN) || (flow_ring_table[id].status == FLOW_RING_STATUS_CREATE_PENDING))) { - DHD_ERROR(("%s: deleting flowid %d\n", + DHD_INFO(("%s: deleting flowid %d\n", __FUNCTION__, flow_ring_table[id].flowid)); dhd_bus_flow_ring_delete_request(dhdp->bus, (void *) &flow_ring_table[id]); @@ -31,6 +31,7 @@ #include <bcmip.h> #include <bcmendian.h> +#include <dhd.h> #include <dhd_dbg.h> #include <dhd_ip.h> diff --git a/dhd_linux.c b/dhd_linux.c index 5199b03..e1369b2 100644 --- a/dhd_linux.c +++ b/dhd_linux.c @@ -48,7 +48,6 @@ #include <linux/spinlock.h> #include <linux/ethtool.h> #include <linux/fcntl.h> -#include <linux/fs.h> #include <linux/ip.h> #include <linux/reboot.h> #include <linux/notifier.h> @@ -61,7 +60,6 @@ #include <linux/cpufreq.h> #endif /* ENABLE_ADAPTIVE_SCHED */ #include <linux/rtc.h> -#include <linux/namei.h> #include <asm/uaccess.h> #include <asm/unaligned.h> #include <dhd_linux_priv.h> @@ -1426,49 +1424,58 @@ dhd_sta_pool_clear(dhd_pub_t *dhdp, int max_sta) } } -/** Find STA with MAC address ea in an interface's STA list. */ +/* + * Lockless variant of dhd_find_sta() + * Find STA with MAC address ea in an interface's STA list. + */ dhd_sta_t * -dhd_find_sta(void *pub, int ifidx, void *ea) +__dhd_find_sta(dhd_if_t *ifp, void *pub, int ifidx, void *ea) { dhd_sta_t *sta; - dhd_if_t *ifp; - unsigned long flags; - ASSERT(ea != NULL); - ifp = dhd_get_ifp((dhd_pub_t *)pub, ifidx); - if (ifp == NULL) - return DHD_STA_NULL; - - DHD_IF_STA_LIST_LOCK(&ifp->sta_list_lock, flags); GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST(); list_for_each_entry(sta, &ifp->sta_list, list) { GCC_DIAGNOSTIC_POP(); if (!memcmp(sta->ea.octet, ea, ETHER_ADDR_LEN)) { DHD_INFO(("%s: Found STA " MACDBG "\n", __FUNCTION__, MAC2STRDBG((char *)ea))); - DHD_IF_STA_LIST_UNLOCK(&ifp->sta_list_lock, flags); return sta; } } - DHD_IF_STA_LIST_UNLOCK(&ifp->sta_list_lock, flags); - return DHD_STA_NULL; } -/** Add STA into the interface's STA list. */ +/** Find STA with MAC address ea in an interface's STA list. */ dhd_sta_t * -dhd_add_sta(void *pub, int ifidx, void *ea) +dhd_find_sta(void *pub, int ifidx, void *ea) { dhd_sta_t *sta; dhd_if_t *ifp; unsigned long flags; - ASSERT(ea != NULL); ifp = dhd_get_ifp((dhd_pub_t *)pub, ifidx); if (ifp == NULL) return DHD_STA_NULL; + DHD_IF_STA_LIST_LOCK(&ifp->sta_list_lock, flags); + + sta = __dhd_find_sta(ifp, pub, ifidx, ea); + + DHD_IF_STA_LIST_UNLOCK(&ifp->sta_list_lock, flags); + + return sta; +} + +/* + * Lockless variant of dhd_add_sta() + * Add STA into the interface's STA list. + */ +dhd_sta_t * +__dhd_add_sta(dhd_if_t *ifp, void *pub, int ifidx, void *ea) +{ + dhd_sta_t *sta; + if (!memcmp(ifp->net->dev_addr, ea, ETHER_ADDR_LEN)) { DHD_ERROR(("%s: Serious FAILURE, receive own MAC %pM !!\n", __FUNCTION__, ea)); return DHD_STA_NULL; @@ -1480,8 +1487,6 @@ dhd_add_sta(void *pub, int ifidx, void *ea) return DHD_STA_NULL; } - DHD_IF_STA_LIST_LOCK(&ifp->sta_list_lock, flags); - memcpy(sta->ea.octet, ea, ETHER_ADDR_LEN); /* link the sta and the dhd interface */ @@ -1497,6 +1502,25 @@ dhd_add_sta(void *pub, int ifidx, void *ea) DHD_ERROR(("%s: Adding STA " MACDBG "\n", __FUNCTION__, MAC2STRDBG((char *)ea))); + return sta; +} + +/** Add STA into the interface's STA list. */ +dhd_sta_t * +dhd_add_sta(void *pub, int ifidx, void *ea) +{ + dhd_sta_t *sta; + dhd_if_t *ifp; + unsigned long flags; + + ifp = dhd_get_ifp((dhd_pub_t *)pub, ifidx); + if (ifp == NULL) + return DHD_STA_NULL; + + DHD_IF_STA_LIST_LOCK(&ifp->sta_list_lock, flags); + + sta = __dhd_add_sta(ifp, pub, ifidx, ea); + DHD_IF_STA_LIST_UNLOCK(&ifp->sta_list_lock, flags); return sta; @@ -1576,13 +1600,22 @@ dhd_sta_t* dhd_findadd_sta(void *pub, int ifidx, void *ea) { dhd_sta_t *sta; + dhd_if_t *ifp; + unsigned long flags; + + ASSERT(ea != NULL); + ifp = dhd_get_ifp((dhd_pub_t *)pub, ifidx); + if (ifp == NULL) + return DHD_STA_NULL; - sta = dhd_find_sta(pub, ifidx, ea); + DHD_IF_STA_LIST_LOCK(&ifp->sta_list_lock, flags); + sta = __dhd_find_sta(ifp, pub, ifidx, ea); if (!sta) { /* Add entry */ - sta = dhd_add_sta(pub, ifidx, ea); + sta = __dhd_add_sta(ifp, pub, ifidx, ea); } + DHD_IF_STA_LIST_UNLOCK(&ifp->sta_list_lock, flags); return sta; } @@ -2682,9 +2715,6 @@ dhd_bssidx2bssid(dhd_pub_t *dhdp, int idx) } #ifdef BCMDBUS -#define DBUS_NRXQ 50 -#define DBUS_NTXQ 100 - static void dhd_dbus_send_complete(void *handle, void *info, int status) { @@ -3901,12 +3931,13 @@ BCMFASTPATH(__dhd_sendpkt)(dhd_pub_t *dhdp, int ifidx, void *pktbuf) if (PKTPRIO(pktbuf) == 0) #endif /* !PKTPRIO_OVERRIDE */ { -#if (!defined(BCM_ROUTER_DHD) && defined(QOS_MAP_SET)) +#if (!defined(BCM_ROUTER_DHD) && (defined(QOS_MAP_SET) || \ + defined(WL_CUSTOM_MAPPING_OF_DSCP))) pktsetprio_qms(pktbuf, wl_get_up_table(dhdp, ifidx), FALSE); #else /* For LLR, pkt prio will be changed to 7(NC) here */ pktsetprio(pktbuf, FALSE); -#endif /* QOS_MAP_SET */ +#endif /* QOS_MAP_SET || WL_CUSTOM_MAPPING_OF_DSCP */ } #ifndef PKTPRIO_OVERRIDE else { @@ -5929,7 +5960,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) skb->len = len; /* TODO: XXX: re-look into dropped packets. */ - DHD_DBG_PKT_MON_RX(dhdp, skb); + DHD_DBG_PKT_MON_RX(dhdp, skb, FRAME_TYPE_ETHERNET_II); /* Strip header, count, deliver upward */ skb_pull(skb, ETH_HLEN); @@ -6103,10 +6134,6 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) if (unlikely(pkt_wake)) { wcp->rxwake++; #ifdef DHD_WAKE_RX_STATUS -#define ETHER_ICMP6_HEADER 20 -#define ETHER_IPV6_SADDR (ETHER_ICMP6_HEADER + 2) -#define ETHER_IPV6_DAADR (ETHER_IPV6_SADDR + IPV6_ADDR_LEN) -#define ETHER_ICMPV6_TYPE (ETHER_IPV6_DAADR + IPV6_ADDR_LEN) if (ntoh16(skb->protocol) == ETHER_TYPE_ARP) /* ARP */ wcp->rx_arp++; @@ -7199,6 +7226,24 @@ static bool dhd_check_hang(struct net_device *net, dhd_pub_t *dhdp, int error) return FALSE; } +#ifdef DBG_PKT_MON +void +dhd_80211_mon_pkt(dhd_pub_t *dhdp, host_rxbuf_cmpl_t* msg, void *pkt, int ifidx) +{ + /* Distinguish rx/tx frame */ + wl_aml_header_v1_t hdr; + + hdr = *(wl_aml_header_v1_t *)PKTDATA(dhdp->osh, pkt); + PKTPULL(dhdp->osh, pkt, sizeof(hdr)); + if (hdr.flags & WL_AML_F_DIRECTION) { + bool ack = !!(hdr.flags & WL_AML_F_ACKED); + DHD_DBG_PKT_MON_TX(dhdp, pkt, 0, FRAME_TYPE_80211_MGMT, (uint8)ack); + } else { + DHD_DBG_PKT_MON_RX(dhdp, (struct sk_buff *)pkt, FRAME_TYPE_80211_MGMT); + } +} +#endif /* DBG_PKT_MON */ + #ifdef WL_MONITOR bool dhd_monitor_enabled(dhd_pub_t *dhd, int ifidx) @@ -9818,7 +9863,7 @@ dhd_os_write_file_posn(void *fp, unsigned long *posn, void *buf, if (!fp || !buf || buflen == 0) return -1; - if (vfs_write((struct file *)fp, buf, buflen, &wr_posn) < 0) + if (dhd_vfs_write((struct file *)fp, buf, buflen, &wr_posn) < 0) return -1; *posn = wr_posn; @@ -9834,7 +9879,7 @@ dhd_os_read_file(void *file, char *buf, uint32 size) if (!file || !buf) return -1; - return vfs_read(filep, buf, size, &filep->f_pos); + return dhd_vfs_read(filep, buf, size, &filep->f_pos); } int @@ -9868,13 +9913,13 @@ dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp) fs = get_fs(); set_fs(KERNEL_DS); - filep = filp_open(logstrs_path, O_RDONLY, 0); + filep = dhd_filp_open(logstrs_path, O_RDONLY, 0); - if (IS_ERR(filep)) { + if (IS_ERR(filep) || (filep == NULL)) { DHD_ERROR_NO_HW4(("%s: Failed to open the file %s \n", __FUNCTION__, logstrs_path)); goto fail; } - error = vfs_stat(logstrs_path, &stat); + error = dhd_vfs_stat(logstrs_path, &stat); if (error) { DHD_ERROR_NO_HW4(("%s: Failed to stat file %s \n", __FUNCTION__, logstrs_path)); goto fail; @@ -9896,14 +9941,14 @@ dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp) } } - if (vfs_read(filep, raw_fmts, logstrs_size, &filep->f_pos) != logstrs_size) { + if (dhd_vfs_read(filep, raw_fmts, logstrs_size, &filep->f_pos) != logstrs_size) { DHD_ERROR_NO_HW4(("%s: Failed to read file %s\n", __FUNCTION__, logstrs_path)); goto fail; } if (dhd_parse_logstrs_file(osh, raw_fmts, logstrs_size, temp) == BCME_OK) { - filp_close(filep, NULL); + dhd_filp_close(filep, NULL); set_fs(fs); return BCME_OK; } @@ -9918,7 +9963,7 @@ fail: fail1: if (!IS_ERR(filep)) - filp_close(filep, NULL); + dhd_filp_close(filep, NULL); set_fs(fs); temp->fmts = NULL; @@ -9943,8 +9988,8 @@ dhd_read_map(osl_t *osh, char *fname, uint32 *ramstart, uint32 *rodata_start, fs = get_fs(); set_fs(KERNEL_DS); - filep = filp_open(fname, O_RDONLY, 0); - if (IS_ERR(filep)) { + filep = dhd_filp_open(fname, O_RDONLY, 0); + if (IS_ERR(filep) || (filep == NULL)) { DHD_ERROR_NO_HW4(("%s: Failed to open %s \n", __FUNCTION__, fname)); goto fail; } @@ -9955,18 +10000,13 @@ dhd_read_map(osl_t *osh, char *fname, uint32 *ramstart, uint32 *rodata_start, fail: if (!IS_ERR(filep)) - filp_close(filep, NULL); + dhd_filp_close(filep, NULL); set_fs(fs); return err; } #ifdef DHD_COREDUMP -#define PC_FOUND_BIT 0x01 -#define LR_FOUND_BIT 0x02 -#define ALL_ADDR_VAL (PC_FOUND_BIT | LR_FOUND_BIT) -#define READ_NUM_BYTES 1000 -#define DHD_FUNC_STR_LEN 80 static int dhd_lookup_map(osl_t *osh, char *fname, uint32 pc, char *pc_fn, uint32 lr, char *lr_fn) @@ -10002,8 +10042,8 @@ dhd_lookup_map(osl_t *osh, char *fname, uint32 pc, char *pc_fn, fs = get_fs(); set_fs(KERNEL_DS); - filep = filp_open(fname, O_RDONLY, 0); - if (IS_ERR(filep)) { + filep = dhd_filp_open(fname, O_RDONLY, 0); + if (IS_ERR(filep) || (filep == NULL)) { DHD_ERROR(("%s: Failed to open %s \n", __FUNCTION__, fname)); goto fail; } @@ -10136,7 +10176,7 @@ dhd_lookup_map(osl_t *osh, char *fname, uint32 pc, char *pc_fn, fail: if (!IS_ERR(filep)) - filp_close(filep, NULL); + dhd_filp_close(filep, NULL); set_fs(fs); @@ -10180,8 +10220,8 @@ dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, ch fs = get_fs(); set_fs(KERNEL_DS); - filep = filp_open(str_file, O_RDONLY, 0); - if (IS_ERR(filep)) { + filep = dhd_filp_open(str_file, O_RDONLY, 0); + if (IS_ERR(filep) || (filep == NULL)) { DHD_ERROR(("%s: Failed to open the file %s \n", __FUNCTION__, str_file)); goto fail; } @@ -10218,7 +10258,7 @@ dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, ch } } - error = vfs_read(filep, raw_fmts, logstrs_size, (&filep->f_pos)); + error = dhd_vfs_read(filep, raw_fmts, logstrs_size, (&filep->f_pos)); if (error != logstrs_size) { DHD_ERROR(("%s: %s read failed %d \n", __FUNCTION__, str_file, error)); goto fail; @@ -10236,7 +10276,7 @@ dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, ch temp->rom_rodata_end = rodata_end; } - filp_close(filep, NULL); + dhd_filp_close(filep, NULL); set_fs(fs); return BCME_OK; @@ -10248,7 +10288,7 @@ fail: fail1: if (!IS_ERR(filep)) - filp_close(filep, NULL); + dhd_filp_close(filep, NULL); set_fs(fs); @@ -11765,9 +11805,6 @@ dhd_get_concurrent_capabilites(dhd_pub_t *dhd) #endif #ifdef SUPPORT_AP_POWERSAVE -#define RXCHAIN_PWRSAVE_PPS 10 -#define RXCHAIN_PWRSAVE_QUIET_TIME 10 -#define RXCHAIN_PWRSAVE_STAS_ASSOC_CHECK 0 int dhd_set_ap_powersave(dhd_pub_t *dhdp, int ifidx, int enable) { int32 pps = RXCHAIN_PWRSAVE_PPS; @@ -12012,7 +12049,7 @@ static int dhd_preinit_config(dhd_pub_t *dhd, int ifidx) old_fs = get_fs(); set_fs(get_ds()); - if ((ret = vfs_stat(config_path, &stat))) { + if ((ret = dhd_vfs_stat(config_path, &stat))) { set_fs(old_fs); printk(KERN_ERR "%s: Failed to get information (%d)\n", config_path, ret); @@ -12069,7 +12106,7 @@ err: } #endif /* READ_CONFIG_FROM_FILE */ -#if defined(WLADPS) +#if defined(WLADPS) || defined(WLADPS_PRIVATE_CMD) int dhd_enable_adps(dhd_pub_t *dhd, uint8 on) @@ -12121,7 +12158,7 @@ exit: } return ret; } -#endif +#endif /* WLADPS || WLADPS_PRIVATE_CMD */ int dhd_get_preserve_log_numbers(dhd_pub_t *dhd, uint32 *logset_mask) @@ -16599,14 +16636,15 @@ dhd_os_open_image1(dhd_pub_t *pub, char *filename) struct file *fp; int size; - fp = filp_open(filename, O_RDONLY, 0); + fp = dhd_filp_open(filename, O_RDONLY, 0); + /* - * 2.6.11 (FC4) supports filp_open() but later revs don't? + * 2.6.11 (FC4) supports dhd_filp_open() but later revs don't? * Alternative: * fp = open_namei(AT_FDCWD, filename, O_RD, 0); * ??? */ - if (IS_ERR(fp)) { + if (IS_ERR(fp) || (fp == NULL)) { fp = NULL; goto err; } @@ -16617,7 +16655,7 @@ dhd_os_open_image1(dhd_pub_t *pub, char *filename) goto err; } - size = i_size_read(file_inode(fp)); + size = dhd_i_size_read(file_inode(fp)); if (size <= 0) { DHD_ERROR(("%s: %s file size invalid %d\n", __FUNCTION__, filename, size)); fp = NULL; @@ -16641,8 +16679,8 @@ dhd_os_get_image_block(char *buf, int len, void *image) return 0; } - size = i_size_read(file_inode(fp)); - rdlen = kernel_read_compat(fp, fp->f_pos, buf, MIN(len, size)); + size = dhd_i_size_read(file_inode(fp)); + rdlen = dhd_kernel_read_compat(fp, fp->f_pos, buf, MIN(len, size)); if (len >= size && size != rdlen) { return -EIO; @@ -16667,7 +16705,7 @@ dhd_os_gets_image(dhd_pub_t *pub, char *str, int len, void *image) if (!image) return 0; - rd_len = kernel_read_compat(fp, fp->f_pos, str, len); + rd_len = dhd_kernel_read_compat(fp, fp->f_pos, str, len); str_end = strnchr(str, len, '\n'); if (str_end == NULL) { goto err; @@ -16692,7 +16730,7 @@ dhd_os_get_image_size(void *image) return 0; } - size = i_size_read(file_inode(fp)); + size = dhd_i_size_read(file_inode(fp)); return size; } @@ -16701,7 +16739,7 @@ void dhd_os_close_image1(dhd_pub_t *pub, void *image) { if (image) { - filp_close((struct file *)image, NULL); + dhd_filp_close((struct file *)image, NULL); } } @@ -17101,14 +17139,59 @@ int dhd_net_bus_suspend(struct net_device *dev) { dhd_info_t *dhd = DHD_DEV_INFO(dev); - return dhd_bus_suspend(&dhd->pub); + uint bitmask = 0xFFFFFFFF; + int timeleft = 0; + unsigned long flags = 0; + int ret = 0; + + DHD_GENERAL_LOCK(&dhd->pub, flags); + if (!DHD_BUS_BUSY_CHECK_IDLE(&dhd->pub)) { + DHD_BUS_BUSY_SET_SUSPEND_IN_PROGRESS(&dhd->pub); + DHD_GENERAL_UNLOCK(&dhd->pub, flags); + DHD_ERROR(("%s: wait to clear dhd_bus_busy_state: 0x%x\n", + __FUNCTION__, dhd->pub.dhd_bus_busy_state)); + timeleft = dhd_os_busbusy_wait_bitmask(&dhd->pub, + &dhd->pub.dhd_bus_busy_state, bitmask, + DHD_BUS_BUSY_SUSPEND_IN_PROGRESS); + if ((timeleft == 0) || (timeleft == 1)) { + DHD_ERROR(("%s: Timed out dhd_bus_busy_state=0x%x\n", + __FUNCTION__, dhd->pub.dhd_bus_busy_state)); + ASSERT(0); + } + } else { + DHD_BUS_BUSY_SET_SUSPEND_IN_PROGRESS(&dhd->pub); + DHD_GENERAL_UNLOCK(&dhd->pub, flags); + } + + ret = dhd_bus_suspend(&dhd->pub); + + DHD_GENERAL_LOCK(&dhd->pub, flags); + DHD_BUS_BUSY_CLEAR_SUSPEND_IN_PROGRESS(&dhd->pub); + dhd_os_busbusy_wake(&dhd->pub); + DHD_GENERAL_UNLOCK(&dhd->pub, flags); + + return ret; } int dhd_net_bus_resume(struct net_device *dev, uint8 stage) { dhd_info_t *dhd = DHD_DEV_INFO(dev); - return dhd_bus_resume(&dhd->pub, stage); + unsigned long flags = 0; + int ret = 0; + + DHD_GENERAL_LOCK(&dhd->pub, flags); + DHD_BUS_BUSY_SET_RESUME_IN_PROGRESS(&dhd->pub); + DHD_GENERAL_UNLOCK(&dhd->pub, flags); + + ret = dhd_bus_resume(&dhd->pub, stage); + + DHD_GENERAL_LOCK(&dhd->pub, flags); + DHD_BUS_BUSY_CLEAR_RESUME_IN_PROGRESS(&dhd->pub); + dhd_os_busbusy_wake(&dhd->pub); + DHD_GENERAL_UNLOCK(&dhd->pub, flags); + + return ret; } #endif /* BCMSDIO || BCMPCIE */ @@ -19050,21 +19133,21 @@ int write_file(const char * file_name, uint32 flags, uint8 *buf, int size) set_fs(KERNEL_DS); /* open file to write */ - fp = filp_open(file_name, flags, 0664); - if (IS_ERR(fp)) { + fp = dhd_filp_open(file_name, flags, 0664); + if (IS_ERR(fp) || (fp == NULL)) { DHD_ERROR(("open file error, err = %ld\n", PTR_ERR(fp))); goto exit; } /* Write buf to file */ - ret = vfs_write(fp, buf, size, &pos); + ret = dhd_vfs_write(fp, buf, size, &pos); if (ret < 0) { DHD_ERROR(("write file error, err = %d\n", ret)); goto exit; } /* Sync file from filesystem to physical media */ - ret = vfs_fsync(fp, 0); + ret = dhd_vfs_fsync(fp, 0); if (ret < 0) { DHD_ERROR(("sync file error, error = %d\n", ret)); goto exit; @@ -19074,7 +19157,7 @@ int write_file(const char * file_name, uint32 flags, uint8 *buf, int size) exit: /* close file before return */ if (!IS_ERR(fp)) - filp_close(fp, current->files); + dhd_filp_close(fp, current->files); /* restore previous address limit */ set_fs(old_fs); @@ -19142,14 +19225,14 @@ write_dump_to_file(dhd_pub_t *dhd, uint8 *buf, int size, char *fname) */ file_mode = O_CREAT | O_WRONLY | O_SYNC; { - struct file *fp = filp_open(memdump_path, file_mode, 0664); + struct file *fp = dhd_filp_open(memdump_path, file_mode, 0664); /* Check if it is live Brix image having /installmedia, else use /data */ - if (IS_ERR(fp)) { + if (IS_ERR(fp) || (fp == NULL)) { DHD_ERROR(("open file %s, try /data/\n", memdump_path)); snprintf(memdump_path, sizeof(memdump_path), "%s%s_%s_" "%s", "/data/", fname, memdump_type, dhd->debug_dump_time_str); } else { - filp_close(fp, NULL); + dhd_filp_close(fp, NULL); } } #endif /* CUSTOMER_HW4_DEBUG */ @@ -21136,7 +21219,6 @@ dhd_sdtc_etb_dump(dhd_pub_t *dhd) etb_info_t etb_info; uint8 *sdtc_etb_dump; uint8 *sdtc_etb_mempool; - uint etb_dump_len; int ret = 0; if (!dhd->sdtc_etb_inited) { @@ -21151,6 +21233,12 @@ dhd_sdtc_etb_dump(dhd_pub_t *dhd) return; } + if (etb_info.addr == (uint32)-1) { + DHD_ERROR(("%s: invalid etbinfo.addr 0x%x Hence donot collect SDTC ETB\n", + __FUNCTION__, etb_info.addr)); + return; + } + if (etb_info.read_bytes == 0) { DHD_ERROR(("%s ETB is of zero size. Hence donot collect SDTC ETB\n", __FUNCTION__)); return; @@ -21164,10 +21252,10 @@ dhd_sdtc_etb_dump(dhd_pub_t *dhd) /* * etb mempool format = etb_info + etb */ - etb_dump_len = etb_info.read_bytes + sizeof(etb_info); - if (etb_dump_len > DHD_SDTC_ETB_MEMPOOL_SIZE) { + dhd->sdtc_etb_dump_len = etb_info.read_bytes + sizeof(etb_info); + if (dhd->sdtc_etb_dump_len > DHD_SDTC_ETB_MEMPOOL_SIZE) { DHD_ERROR(("%s etb_dump_len: %d is more than the alloced %d.Hence cannot collect\n", - __FUNCTION__, etb_dump_len, DHD_SDTC_ETB_MEMPOOL_SIZE)); + __FUNCTION__, dhd->sdtc_etb_dump_len, DHD_SDTC_ETB_MEMPOOL_SIZE)); return; } sdtc_etb_mempool = dhd->sdtc_etb_mempool; @@ -21178,11 +21266,37 @@ dhd_sdtc_etb_dump(dhd_pub_t *dhd) return; } + dhd_print_buf_addr(dhd, "sdtc_etb_dump", (uint8 *)sdtc_etb_mempool, dhd->sdtc_etb_dump_len); + /* + * If kernel does not have file write access enabled + * then skip writing dumps to files. + * The dumps will be pushed to HAL layer which will + * write into files + */ +#ifdef DHD_DUMP_FILE_WRITE_FROM_KERNEL if (write_dump_to_file(dhd, (uint8 *)sdtc_etb_mempool, - etb_dump_len, "sdtc_etb_dump")) { + dhd->sdtc_etb_dump_len, "sdtc_etb_dump")) { DHD_ERROR(("%s: failed to dump sdtc_etb to file\n", __FUNCTION__)); } +#endif /* DHD_DUMP_FILE_WRITE_FROM_KERNEL */ +} + +int +dhd_sdtc_etb_hal_file_dump(void *dev, const void *user_buf, uint32 len) +{ + dhd_info_t *dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)dev); + dhd_pub_t *dhdp = &dhd_info->pub; + int pos = 0, ret = BCME_ERROR; + + if (dhdp->sdtc_etb_dump_len) { + ret = dhd_export_debug_data((char *)dhdp->sdtc_etb_mempool, + NULL, user_buf, dhdp->sdtc_etb_dump_len, &pos); + } else { + DHD_ERROR(("%s ETB is of zero size. Hence donot collect SDTC ETB\n", __FUNCTION__)); + } + DHD_ERROR(("%s, done ret: %d\n", __FUNCTION__, ret)); + return ret; } #endif /* DHD_SDTC_ETB_DUMP */ @@ -22311,8 +22425,8 @@ do_dhd_log_dump(dhd_pub_t *dhdp, log_dump_type_t *type) else file_mode = O_CREAT | O_RDWR | O_SYNC; - fp = filp_open(dump_path, file_mode, 0664); - if (IS_ERR(fp)) { + fp = dhd_filp_open(dump_path, file_mode, 0664); + if (IS_ERR(fp) || (fp == NULL)) { /* If android installed image, try '/data' directory */ #if defined(CONFIG_X86) DHD_ERROR(("%s: File open error on Installed android image, trying /data...\n", @@ -22323,8 +22437,8 @@ do_dhd_log_dump(dhd_pub_t *dhdp, log_dump_type_t *type) sizeof(dump_path) - strlen(dump_path), "_%s", dhdp->debug_dump_time_str); } - fp = filp_open(dump_path, file_mode, 0664); - if (IS_ERR(fp)) { + fp = dhd_filp_open(dump_path, file_mode, 0664); + if (IS_ERR(fp) || (fp == NULL)) { ret = PTR_ERR(fp); DHD_ERROR(("open file error, err = %d\n", ret)); goto exit2; @@ -22337,7 +22451,7 @@ do_dhd_log_dump(dhd_pub_t *dhdp, log_dump_type_t *type) #endif /* CONFIG_X86 && OEM_ANDROID */ } - ret = vfs_stat(dump_path, &stat); + ret = dhd_vfs_stat(dump_path, &stat); if (ret < 0) { DHD_ERROR(("file stat error, err = %d\n", ret)); goto exit2; @@ -22498,7 +22612,7 @@ do_dhd_log_dump(dhd_pub_t *dhdp, log_dump_type_t *type) exit2: if (!IS_ERR(fp) && fp != NULL) { - filp_close(fp, NULL); + dhd_filp_close(fp, NULL); DHD_ERROR(("%s: Finished writing log dump to file - '%s' \n", __FUNCTION__, dump_path)); } @@ -22531,7 +22645,7 @@ dhd_export_debug_data(void *mem_buf, void *fp, const void *user_buf, uint32 buf_ int ret = BCME_OK; if (fp) { - ret = vfs_write(fp, mem_buf, buf_len, (loff_t *)pos); + ret = dhd_vfs_write(fp, mem_buf, buf_len, (loff_t *)pos); if (ret < 0) { DHD_ERROR(("write file error, err = %d\n", ret)); goto exit; @@ -24022,8 +24136,8 @@ dhd_set_blob_support(dhd_pub_t *dhdp, char *fw_path) struct file *fp; char *filepath = VENDOR_PATH CONFIG_BCMDHD_CLM_PATH; - fp = filp_open(filepath, O_RDONLY, 0); - if (IS_ERR(fp)) { + fp = dhd_filp_open(filepath, O_RDONLY, 0); + if (IS_ERR(fp) || (fp == NULL)) { DHD_ERROR(("%s: ----- blob file doesn't exist (%s) -----\n", __FUNCTION__, filepath)); dhdp->is_blob = FALSE; @@ -24035,7 +24149,7 @@ dhd_set_blob_support(dhd_pub_t *dhdp, char *fw_path) #else BCM_REFERENCE(fw_path); #endif /* SKIP_CONCATE_BLOB */ - filp_close(fp, NULL); + dhd_filp_close(fp, NULL); } } #endif /* DHD_LINUX_STD_FW_API */ @@ -24074,108 +24188,6 @@ dhd_schedule_dmaxfer_free(dhd_pub_t *dhdp, dmaxref_mem_map_t *dmmap) } #endif /* PCIE_FULL_DONGLE */ /* ---------------------------- End of sysfs implementation ------------------------------------- */ -#ifdef SET_PCIE_IRQ_CPU_CORE -void -dhd_set_irq_cpucore(dhd_pub_t *dhdp, int affinity_cmd) -{ - unsigned int pcie_irq = 0; -#if defined(DHD_LB) && defined(DHD_LB_HOST_CTRL) - struct dhd_info *dhd = NULL; -#endif /* DHD_LB && DHD_LB_HOST_CTRL */ - - if (!dhdp) { - DHD_ERROR(("%s : dhd is NULL\n", __FUNCTION__)); - return; - } - - if (!dhdp->bus) { - DHD_ERROR(("%s : dhd->bus is NULL\n", __FUNCTION__)); - return; - } - - if (affinity_cmd < DHD_AFFINITY_OFF || affinity_cmd > DHD_AFFINITY_LAST) { - DHD_ERROR(("Wrong Affinity cmds:%d, %s\n", affinity_cmd, __FUNCTION__)); - return; - } - - DHD_ERROR(("Enter %s, PCIe affinity cmd=0x%x\n", __FUNCTION__, affinity_cmd)); - - if (dhdpcie_get_pcieirq(dhdp->bus, &pcie_irq)) { - DHD_ERROR(("%s : Can't get interrupt number\n", __FUNCTION__)); - return; - } - -#if defined(DHD_LB) && defined(DHD_LB_HOST_CTRL) - dhd = dhdp->info; - - if (affinity_cmd == DHD_AFFINITY_OFF) { - dhd->permitted_primary_cpu = FALSE; - } else if (affinity_cmd == DHD_AFFINITY_TPUT_150MBPS || - affinity_cmd == DHD_AFFINITY_TPUT_300MBPS) { - dhd->permitted_primary_cpu = TRUE; - } - dhd_select_cpu_candidacy(dhd); - /* - * It needs to NAPI disable -> enable to raise NET_RX napi CPU core - * during Rx traffic - * NET_RX does not move to NAPI CPU core if continusly calling napi polling - * function - */ - napi_disable(&dhd->rx_napi_struct); - napi_enable(&dhd->rx_napi_struct); -#endif /* DHD_LB && DHD_LB_HOST_CTRL */ - - /* - irq_set_affinity() assign dedicated CPU core PCIe interrupt - If dedicated CPU core is not on-line, - PCIe interrupt scheduled on CPU core 0 - */ -#if defined(CONFIG_ARCH_SM8150) || defined(CONFIG_ARCH_KONA) - /* For SDM platform */ - switch (affinity_cmd) { - case DHD_AFFINITY_OFF: -#if defined(DHD_LB) && defined(DHD_LB_HOST_CTRL) - irq_set_affinity_hint(pcie_irq, dhdp->info->cpumask_secondary); - irq_set_affinity(pcie_irq, dhdp->info->cpumask_secondary); -#endif /* DHD_LB && DHD_LB_HOST_CTRL */ - break; - case DHD_AFFINITY_TPUT_150MBPS: - case DHD_AFFINITY_TPUT_300MBPS: - irq_set_affinity_hint(pcie_irq, dhdp->info->cpumask_primary); - irq_set_affinity(pcie_irq, dhdp->info->cpumask_primary); - break; - default: - DHD_ERROR(("%s, Unknown PCIe affinity cmd=0x%x\n", - __FUNCTION__, affinity_cmd)); - } -#elif defined(CONFIG_SOC_EXYNOS9810) || defined(CONFIG_SOC_EXYNOS9820) || \ - defined(CONFIG_SOC_EXYNOS9830) - /* For Exynos platform */ - switch (affinity_cmd) { - case DHD_AFFINITY_OFF: -#if defined(DHD_LB) && defined(DHD_LB_HOST_CTRL) - irq_set_affinity(pcie_irq, dhdp->info->cpumask_secondary); -#endif /* DHD_LB && DHD_LB_HOST_CTRL */ - break; - case DHD_AFFINITY_TPUT_150MBPS: - irq_set_affinity(pcie_irq, dhdp->info->cpumask_primary); - break; - case DHD_AFFINITY_TPUT_300MBPS: - DHD_ERROR(("%s, PCIe IRQ:%u set Core %d\n", - __FUNCTION__, pcie_irq, PCIE_IRQ_CPU_CORE)); - irq_set_affinity(pcie_irq, cpumask_of(PCIE_IRQ_CPU_CORE)); - break; - default: - DHD_ERROR(("%s, Unknown PCIe affinity cmd=0x%x\n", - __FUNCTION__, affinity_cmd)); - } -#else /* For Undefined platform */ - DHD_ERROR(("%s, Unknown PCIe affinity cmd=0x%x\n", - __FUNCTION__, affinity_cmd)); -#endif /* End of Platfrom define */ - -} -#endif /* SET_PCIE_IRQ_CPU_CORE */ int dhd_write_file(const char *filepath, char *buf, int buf_len) @@ -24189,14 +24201,14 @@ dhd_write_file(const char *filepath, char *buf, int buf_len) set_fs(KERNEL_DS); /* File is always created. */ - fp = filp_open(filepath, O_RDWR | O_CREAT, 0664); - if (IS_ERR(fp)) { + fp = dhd_filp_open(filepath, O_RDWR | O_CREAT, 0664); + if (IS_ERR(fp) || (fp == NULL)) { DHD_ERROR(("%s: Couldn't open file '%s' err %ld\n", __FUNCTION__, filepath, PTR_ERR(fp))); ret = BCME_ERROR; } else { if (fp->f_mode & FMODE_WRITE) { - ret = vfs_write(fp, buf, buf_len, &fp->f_pos); + ret = dhd_vfs_write(fp, buf, buf_len, &fp->f_pos); if (ret < 0) { DHD_ERROR(("%s: Couldn't write file '%s'\n", __FUNCTION__, filepath)); @@ -24205,7 +24217,7 @@ dhd_write_file(const char *filepath, char *buf, int buf_len) ret = BCME_OK; } } - filp_close(fp, NULL); + dhd_filp_close(fp, NULL); } /* restore previous address limit */ @@ -24225,15 +24237,15 @@ dhd_read_file(const char *filepath, char *buf, int buf_len) old_fs = get_fs(); set_fs(KERNEL_DS); - fp = filp_open(filepath, O_RDONLY, 0); - if (IS_ERR(fp)) { + fp = dhd_filp_open(filepath, O_RDONLY, 0); + if (IS_ERR(fp) || (fp == NULL)) { set_fs(old_fs); DHD_ERROR(("%s: File %s doesn't exist\n", __FUNCTION__, filepath)); return BCME_ERROR; } - ret = kernel_read_compat(fp, 0, buf, buf_len); - filp_close(fp, NULL); + ret = dhd_kernel_read_compat(fp, 0, buf, buf_len); + dhd_filp_close(fp, NULL); /* restore previous address limit */ set_fs(old_fs); @@ -26267,19 +26279,23 @@ dhd_ring_whole_unlock(void *_ring) #define DHD_VFS_INODE(dir) d_inode(dir) #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0) */ +#ifdef DHD_SUPPORT_VFS_CALL #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)) #define DHD_VFS_UNLINK(dir, b, c) vfs_unlink(DHD_VFS_INODE(dir), b) #else #define DHD_VFS_UNLINK(dir, b, c) vfs_unlink(DHD_VFS_INODE(dir), b, c) #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) */ +#else +#define DHD_VFS_UNLINK(dir, b, c) 0 +#endif /* DHD_SUPPORT_VFS_CALL */ int dhd_file_delete(char *path) { - struct path file_path; + struct path file_path = {.dentry = 0}; int err; struct dentry *dir; - err = kern_path(path, 0, &file_path); + err = dhd_kern_path(path, 0, &file_path); if (err < 0) { DHD_ERROR(("Failed to get kern-path delete file: %s error: %d\n", path, err)); @@ -26648,6 +26664,10 @@ dhd_net_del_flowrings_sta(dhd_pub_t *dhd, struct net_device *ndev) __FUNCTION__, ifp->idx)); dhd_del_all_sta(dhd, ifp->idx); + /* Try to resume if already suspended or suspend in progress */ +#ifdef DHD_PCIE_RUNTIMEPM + dhdpcie_runtime_bus_wake(dhd, CAN_SLEEP(), __builtin_return_address(0)); +#endif /* DHD_PCIE_RUNTIMEPM */ dhd_flow_rings_delete(dhd, ifp->idx); } #endif /* PCIE_FULL_DONGLE */ diff --git a/dhd_linux.h b/dhd_linux.h index 19443a3..fef49a7 100644 --- a/dhd_linux.h +++ b/dhd_linux.h @@ -65,6 +65,32 @@ #endif /* HOST_RADIOTAP_CONV */ #endif /* WL_MONITOR */ +#ifdef DHD_COREDUMP +#define PC_FOUND_BIT 0x01 +#define LR_FOUND_BIT 0x02 +#define ALL_ADDR_VAL (PC_FOUND_BIT | LR_FOUND_BIT) +#define READ_NUM_BYTES 1000 +#define DHD_FUNC_STR_LEN 80 +#endif /* DHD_COREDUMP */ + +#ifdef BCMDBUS +#define DBUS_NRXQ 50 +#define DBUS_NTXQ 100 +#endif /* BCMDBUS */ + +#ifdef DHD_WAKE_RX_STATUS +#define ETHER_ICMP6_HEADER 20 +#define ETHER_IPV6_SADDR (ETHER_ICMP6_HEADER + 2) +#define ETHER_IPV6_DAADR (ETHER_IPV6_SADDR + IPV6_ADDR_LEN) +#define ETHER_ICMPV6_TYPE (ETHER_IPV6_DAADR + IPV6_ADDR_LEN) +#endif /* DHD_WAKE_RX_STATUS */ + +#ifdef SUPPORT_AP_POWERSAVE +#define RXCHAIN_PWRSAVE_PPS 10 +#define RXCHAIN_PWRSAVE_QUIET_TIME 10 +#define RXCHAIN_PWRSAVE_STAS_ASSOC_CHECK 0 +#endif /* SUPPORT_AP_POWERSAVE */ + #define DHD_REGISTRATION_TIMEOUT 12000 /* msec : allowed time to finished dhd registration */ typedef struct wifi_adapter_info { @@ -429,12 +455,12 @@ void dhd_update_psta_interface_for_sta(dhd_pub_t *dhdp, char* ifname, int dhd_net_bus_get(struct net_device *dev); int dhd_net_bus_put(struct net_device *dev); #endif /* BT_OVER_SDIO */ -#if defined(WLADPS) +#if defined(WLADPS) || defined(WLADPS_PRIVATE_CMD) #define ADPS_ENABLE 1 #define ADPS_DISABLE 0 int dhd_enable_adps(dhd_pub_t *dhd, uint8 on); -#endif +#endif /* WLADPS || WLADPS_PRIVATE_CMD */ #ifdef DHDTCPSYNC_FLOOD_BLK extern void dhd_reset_tcpsync_info_by_ifp(dhd_if_t *ifp); extern void dhd_reset_tcpsync_info_by_dev(struct net_device *dev); diff --git a/dhd_linux_exportfs.c b/dhd_linux_exportfs.c index bfb625f..fa687f6 100644 --- a/dhd_linux_exportfs.c +++ b/dhd_linux_exportfs.c @@ -834,8 +834,8 @@ get_mem_val_from_file(void) int ret = 0; /* Read memdump info from the file */ - fp = filp_open(filepath, O_RDONLY, 0); - if (IS_ERR(fp)) { + fp = dhd_filp_open(filepath, O_RDONLY, 0); + if (IS_ERR(fp) || (fp == NULL)) { DHD_ERROR(("%s: File [%s] doesn't exist\n", __FUNCTION__, filepath)); #if defined(CONFIG_X86) /* Check if it is Live Brix Image */ @@ -845,8 +845,8 @@ get_mem_val_from_file(void) /* Try if it is Installed Brix Image */ filepath = MEMDUMPINFO_INST; DHD_ERROR(("%s: Try File [%s]\n", __FUNCTION__, filepath)); - fp = filp_open(filepath, O_RDONLY, 0); - if (IS_ERR(fp)) { + fp = dhd_filp_open(filepath, O_RDONLY, 0); + if (IS_ERR(fp) || (fp == NULL)) { DHD_ERROR(("%s: File [%s] doesn't exist\n", __FUNCTION__, filepath)); goto done; } @@ -856,10 +856,10 @@ get_mem_val_from_file(void) } /* Handle success case */ - ret = kernel_read_compat(fp, 0, (char *)&mem_val, sizeof(uint32)); + ret = dhd_kernel_read_compat(fp, 0, (char *)&mem_val, sizeof(uint32)); if (ret < 0) { DHD_ERROR(("%s: File read error, ret=%d\n", __FUNCTION__, ret)); - filp_close(fp, NULL); + dhd_filp_close(fp, NULL); goto done; } @@ -867,7 +867,7 @@ get_mem_val_from_file(void) p_mem_val[sizeof(uint32) - 1] = '\0'; mem_val = bcm_atoi(p_mem_val); - filp_close(fp, NULL); + dhd_filp_close(fp, NULL); done: return mem_val; @@ -976,11 +976,11 @@ get_assert_val_from_file(void) * 2: Trigger Kernel crash by BUG() * File doesn't exist: Keep default value (1). */ - fp = filp_open(filepath, O_RDONLY, 0); - if (IS_ERR(fp)) { + fp = dhd_filp_open(filepath, O_RDONLY, 0); + if (IS_ERR(fp) || (fp == NULL)) { DHD_ERROR(("%s: File [%s] doesn't exist\n", __FUNCTION__, filepath)); } else { - int ret = kernel_read_compat(fp, 0, (char *)&mem_val, sizeof(uint32)); + int ret = dhd_kernel_read_compat(fp, 0, (char *)&mem_val, sizeof(uint32)); if (ret < 0) { DHD_ERROR(("%s: File read error, ret=%d\n", __FUNCTION__, ret)); } else { @@ -989,7 +989,7 @@ get_assert_val_from_file(void) mem_val = bcm_atoi(p_mem_val); DHD_ERROR(("%s: ASSERT ENABLED = %d\n", __FUNCTION__, mem_val)); } - filp_close(fp, NULL); + dhd_filp_close(fp, NULL); } #ifdef CUSTOMER_HW4_DEBUG @@ -1728,7 +1728,8 @@ static const struct { {WL_DBG_DBG, "DBG"}, {WL_DBG_SCAN, "SCAN"}, {WL_DBG_TRACE, "TRACE"}, - {WL_DBG_P2P_ACTION, "P2PACTION"} + {WL_DBG_P2P_ACTION, "P2PACTION"}, + {WL_DBG_PNO, "PNO"} }; /** diff --git a/dhd_linux_lb.c b/dhd_linux_lb.c index 8923fd3..656fec7 100644 --- a/dhd_linux_lb.c +++ b/dhd_linux_lb.c @@ -1361,7 +1361,7 @@ dhd_lb_tx_handler(unsigned long data) #endif /* DHD_LB_TXP */ #endif /* DHD_LB */ -#if defined(DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON) +#if defined(SET_PCIE_IRQ_CPU_CORE) || defined(DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON) void dhd_irq_set_affinity(dhd_pub_t *dhdp, const struct cpumask *cpumask) { @@ -1391,4 +1391,77 @@ dhd_irq_set_affinity(dhd_pub_t *dhdp, const struct cpumask *cpumask) DHD_ERROR(("%s : irq set affinity is failed cpu:0x%lx\n", __FUNCTION__, *cpumask_bits(cpumask))); } -#endif /* DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON */ +#endif /* SET_PCIE_IRQ_CPU_CORE || DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON */ + +#ifdef SET_PCIE_IRQ_CPU_CORE +void +dhd_set_irq_cpucore(dhd_pub_t *dhdp, int affinity_cmd) +{ +#if defined(DHD_LB) && defined(DHD_LB_HOST_CTRL) + struct dhd_info *dhd = NULL; +#endif /* DHD_LB && DHD_LB_HOST_CTRL */ + + if (!dhdp) { + DHD_ERROR(("%s : dhd is NULL\n", __FUNCTION__)); + return; + } + + if (!dhdp->bus) { + DHD_ERROR(("%s : dhd->bus is NULL\n", __FUNCTION__)); + return; + } + + if (affinity_cmd < DHD_AFFINITY_OFF || affinity_cmd > DHD_AFFINITY_LAST) { + DHD_ERROR(("Wrong Affinity cmds:%d, %s\n", affinity_cmd, __FUNCTION__)); + return; + } + + DHD_ERROR(("Enter %s, PCIe affinity cmd=0x%x\n", __FUNCTION__, affinity_cmd)); + +#if defined(DHD_LB) && defined(DHD_LB_HOST_CTRL) + dhd = dhdp->info; + + if (affinity_cmd == DHD_AFFINITY_OFF) { + dhd->permitted_primary_cpu = FALSE; + } else if (affinity_cmd == DHD_AFFINITY_TPUT_150MBPS || + affinity_cmd == DHD_AFFINITY_TPUT_300MBPS) { + dhd->permitted_primary_cpu = TRUE; + } + dhd_select_cpu_candidacy(dhd); + /* + * It needs to NAPI disable -> enable to raise NET_RX napi CPU core + * during Rx traffic + * NET_RX does not move to NAPI CPU core if continusly calling napi polling + * function + */ + napi_disable(&dhd->rx_napi_struct); + napi_enable(&dhd->rx_napi_struct); +#endif /* DHD_LB && DHD_LB_HOST_CTRL */ + + /* + irq_set_affinity() assign dedicated CPU core PCIe interrupt + If dedicated CPU core is not on-line, + PCIe interrupt scheduled on CPU core 0 + */ + switch (affinity_cmd) { + case DHD_AFFINITY_OFF: +#if defined(DHD_LB) && defined(DHD_LB_HOST_CTRL) + dhd_irq_set_affinity(dhdp, dhdp->info->cpumask_secondary); +#endif /* DHD_LB && DHD_LB_HOST_CTRL */ + break; + case DHD_AFFINITY_TPUT_150MBPS: + dhd_irq_set_affinity(dhdp, dhdp->info->cpumask_primary); + break; + case DHD_AFFINITY_TPUT_300MBPS: +#ifdef CONFIG_ARCH_EXYNOS + dhd_irq_set_affinity(dhdp, cpumask_of(PCIE_IRQ_CPU_CORE)); +#else + dhd_irq_set_affinity(dhdp, dhdp->info->cpumask_primary); +#endif /* CONFIG_ARCH_EXYNOS */ + break; + default: + DHD_ERROR(("%s, Unknown PCIe affinity cmd=0x%x\n", + __FUNCTION__, affinity_cmd)); + } +} +#endif /* SET_PCIE_IRQ_CPU_CORE */ diff --git a/dhd_linux_priv.h b/dhd_linux_priv.h index 1ee5dbf..85821b9 100644 --- a/dhd_linux_priv.h +++ b/dhd_linux_priv.h @@ -455,10 +455,10 @@ int dhd_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcp int dhd_register_cpuhp_callback(dhd_info_t *dhd); int dhd_unregister_cpuhp_callback(dhd_info_t *dhd); #endif /* DHD_LB */ - -#if defined(DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON) +#if defined(SET_PCIE_IRQ_CPU_CORE) || defined(DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON) void dhd_irq_set_affinity(dhd_pub_t *dhdp, const struct cpumask *cpumask); -#endif /* DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON */ +#endif /* SET_PCIE_IRQ_CPU_CORE || DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON */ + #ifdef DHD_SSSR_DUMP extern uint sssr_enab; extern uint fis_enab; diff --git a/dhd_linux_wq.h b/dhd_linux_wq.h index 2a5f2cd..f34f309 100644 --- a/dhd_linux_wq.h +++ b/dhd_linux_wq.h @@ -53,6 +53,7 @@ enum _wq_event { DHD_WQ_WORK_H2D_CONSOLE_TIME_STAMP_MATCH, DHD_WQ_WORK_AXI_ERROR_DUMP, DHD_WQ_WORK_CTO_RECOVERY, + DHD_WQ_WORK_AML_IOVAR, DHD_MAX_WQ_EVENTS }; diff --git a/dhd_msgbuf.c b/dhd_msgbuf.c index 45b2143..a782f1b 100644 --- a/dhd_msgbuf.c +++ b/dhd_msgbuf.c @@ -843,9 +843,12 @@ static void dhd_prot_process_flow_ring_resume_response(dhd_pub_t *dhd, void* msg static void dhd_prot_process_flow_ring_suspend_response(dhd_pub_t *dhd, void* msg); /* Monitor Mode */ -#ifdef WL_MONITOR +#if defined(WL_MONITOR) extern bool dhd_monitor_enabled(dhd_pub_t *dhd, int ifidx); extern void dhd_rx_mon_pkt(dhd_pub_t *dhdp, host_rxbuf_cmpl_t* msg, void *pkt, int ifidx); +#if defined(DBG_PKT_MON) +extern void dhd_80211_mon_pkt(dhd_pub_t *dhdp, host_rxbuf_cmpl_t* msg, void *pkt, int ifidx); +#endif /* DBG_PKT_MON */ #endif /* WL_MONITOR */ /* Configure a soft doorbell per D2H ring */ @@ -6361,6 +6364,14 @@ BCMFASTPATH(dhd_prot_process_msgbuf_rxcpl)(dhd_pub_t *dhd, uint bound, int ringt DHD_ERROR(("Received non 802.11 packet, " "when monitor mode is enabled\n")); } +#ifdef DBG_PKT_MON + } else { + if (msg->flags & BCMPCIE_PKT_FLAGS_FRAME_802_11) { + DHD_TRACE(("Received 802.11 packet for PKT MON\n")); + dhd_80211_mon_pkt(dhd, msg, pkt, ifidx); + continue; + } +#endif /* DBG_PKT_MON */ } #endif /* WL_MONITOR */ @@ -7638,7 +7649,7 @@ BCMFASTPATH(dhd_prot_txdata)(dhd_pub_t *dhd, void *PKTBUF, uint8 ifidx) pktlen = PKTLEN(dhd->osh, PKTBUF); /* TODO: XXX: re-look into dropped packets */ - DHD_DBG_PKT_MON_TX(dhd, PKTBUF, pktid); + DHD_DBG_PKT_MON_TX(dhd, PKTBUF, pktid, FRAME_TYPE_ETHERNET_II, 0); dhd_handle_pktdata(dhd, ifidx, PKTBUF, pktdata, pktid, pktlen, NULL, &dhd_udr, TRUE, FALSE, TRUE); @@ -10588,7 +10588,7 @@ dhd_bus_inb_ack_pending_ds_req(dhd_bus_t *bus) */ if ((dhdpcie_bus_get_pcie_inband_dw_state(bus) == DW_DEVICE_DS_DEV_SLEEP_PEND) && - (bus->host_active_cnt == 0)) { + (bus->host_active_cnt == 0) && (!bus->skip_ds_ack)) { dhdpcie_bus_set_pcie_inband_dw_state(bus, DW_DEVICE_DS_DEV_SLEEP); dhdpcie_send_mb_data(bus, H2D_HOST_DS_ACK); } @@ -10711,7 +10711,7 @@ dhd_bus_inb_set_device_wake(struct dhd_bus *bus, bool val) bus->inband_dw_deassert_cnt++; } else if ((dhdpcie_bus_get_pcie_inband_dw_state(bus) == DW_DEVICE_DS_DEV_SLEEP_PEND) && - (bus->host_active_cnt == 0)) { + (bus->host_active_cnt == 0) && (!bus->skip_ds_ack)) { dhdpcie_bus_set_pcie_inband_dw_state(bus, DW_DEVICE_DS_DEV_SLEEP); dhdpcie_send_mb_data(bus, H2D_HOST_DS_ACK); } @@ -11838,9 +11838,7 @@ dhdpcie_readshared(dhd_bus_t *bus) #endif /* defined(PCIE_INB_DW) */ uint32 timeout = MAX_READ_TIMEOUT; uint32 elapsed; -#ifndef CUSTOMER_HW4_DEBUG uint32 intstatus; -#endif /* OEM_ANDROID */ if (MULTIBP_ENAB(bus->sih)) { dhd_bus_pcie_pwr_req(bus); @@ -11869,10 +11867,14 @@ dhdpcie_readshared(dhd_bus_t *bus) if (addr == (uint32)-1) { DHD_ERROR(("%s: ##### pciedev shared address is 0xffffffff ####\n", __FUNCTION__)); -#ifdef CUSTOMER_HW4_DEBUG +/* In phones sometimes NOC is seen for any further access after readshared fails */ +#ifdef DHD_NO_DUMP_FOR_READSHARED_FAIL + DHD_ERROR(("%s:### NO dumps will be colelcted and will be marked as linkdown ###\n", + __FUNCTION__)); bus->is_linkdown = 1; - DHD_ERROR(("%s : PCIe link might be down\n", __FUNCTION__)); -#else + return BCME_ERROR; +#endif /* DHD_NO_DUMP_FOR_READSHARED_FAIL */ + dhd_bus_dump_imp_cfg_registers(bus); dhd_bus_dump_dar_registers(bus); /* Check the PCIe link status by reading intstatus register */ @@ -11884,22 +11886,17 @@ dhdpcie_readshared(dhd_bus_t *bus) } else { #if defined(DHD_FW_COREDUMP) #ifdef DHD_SSSR_DUMP -#ifdef BOARD_HIKEY DHD_ERROR(("%s : Set collect_sssr and fis_enab as TRUE\n", __FUNCTION__)); bus->dhd->collect_sssr = TRUE; fis_enab = TRUE; -#endif /* BOARD_HIKEY */ #endif /* DHD_SSSR_DUMP */ /* save core dump or write to a file */ if (bus->dhd->memdump_enabled) { - /* since dhdpcie_readshared() is invoked only during init or trap */ - bus->dhd->memdump_type = bus->dhd->dongle_trap_data ? - DUMP_TYPE_DONGLE_TRAP : DUMP_TYPE_DONGLE_INIT_FAILURE; + bus->dhd->memdump_type = DUMP_TYPE_READ_SHM_FAIL; dhdpcie_mem_dump(bus); } #endif /* DHD_FW_COREDUMP */ } -#endif /* CUSTOMER_HW4_DEBUG */ return BCME_ERROR; } @@ -14903,6 +14900,55 @@ dhdpcie_sssr_dump_get_after_sr(dhd_pub_t *dhd) return BCME_OK; } +#define GCI_CHIPSTATUS_AUX GCI_CHIPSTATUS_10 +#define GCI_CHIPSTATUS_MAIN GCI_CHIPSTATUS_11 +#define GCI_CHIPSTATUS_DIG GCI_CHIPSTATUS_12 +#define GCI_CHIPSTATUS_SCAN GCI_CHIPSTATUS_13 + +#define GCI_CHIPSTATUS_ILLEGAL_INSTR_BITMASK (1u << 3) +int +dhdpcie_validate_gci_chip_intstatus(dhd_pub_t *dhd) +{ + int gci_intstatus; + si_t *sih = dhd->bus->sih; + + /* For now validate only for 4389 chip */ + if (si_chipid(sih) != BCM4389_CHIP_ID) { + DHD_ERROR(("%s: skipping for chipid:0x%x\n", __FUNCTION__, si_chipid(sih))); + return BCME_OK; + } + + gci_intstatus = si_gci_chipstatus(sih, GCI_CHIPSTATUS_MAIN); + if (gci_intstatus & GCI_CHIPSTATUS_ILLEGAL_INSTR_BITMASK) { + DHD_ERROR(("%s: Illegal instruction set for MAIN core 0x%x\n", + __FUNCTION__, gci_intstatus)); + return BCME_ERROR; + } + + gci_intstatus = si_gci_chipstatus(sih, GCI_CHIPSTATUS_AUX); + if (gci_intstatus & GCI_CHIPSTATUS_ILLEGAL_INSTR_BITMASK) { + DHD_ERROR(("%s: Illegal instruction set for AUX core 0x%x\n", + __FUNCTION__, gci_intstatus)); + return BCME_ERROR; + } + + gci_intstatus = si_gci_chipstatus(sih, GCI_CHIPSTATUS_SCAN); + if (gci_intstatus & GCI_CHIPSTATUS_ILLEGAL_INSTR_BITMASK) { + DHD_ERROR(("%s: Illegal instruction set for SCAN core 0x%x\n", + __FUNCTION__, gci_intstatus)); + return BCME_ERROR; + } + + gci_intstatus = si_gci_chipstatus(sih, GCI_CHIPSTATUS_DIG); + if (gci_intstatus & GCI_CHIPSTATUS_ILLEGAL_INSTR_BITMASK) { + DHD_ERROR(("%s: Illegal instruction set for DIG core 0x%x\n", + __FUNCTION__, gci_intstatus)); + return BCME_ERROR; + } + + return BCME_OK; +} + int dhdpcie_sssr_dump(dhd_pub_t *dhd) { @@ -14918,6 +14964,11 @@ dhdpcie_sssr_dump(dhd_pub_t *dhd) return BCME_ERROR; } + if (dhdpcie_validate_gci_chip_intstatus(dhd) != BCME_OK) { + DHD_ERROR(("%s: ## Invalid GCI Chip intstatus, Abort SSSR ##\n", + __FUNCTION__)); + return BCME_ERROR; + } DHD_ERROR(("%s: Before WL down (powerctl: pcie:0x%x chipc:0x%x) " "PMU rctl:0x%x res_state:0x%x\n", __FUNCTION__, si_corereg(dhd->bus->sih, dhd->bus->sih->buscoreidx, @@ -15152,6 +15203,8 @@ dhdpcie_fis_dump(dhd_pub_t *dhd) { int i; uint8 num_d11cores; + struct dhd_bus *bus = dhd->bus; + uint32 save_idx = 0; DHD_ERROR(("%s\n", __FUNCTION__)); @@ -15189,6 +15242,16 @@ dhdpcie_fis_dump(dhd_pub_t *dhd) dhdpcie_d11_check_outofreset(dhd); + /* take sysmem out of reset - otherwise + * socram collected again will read only + * 0xffff + */ + save_idx = si_coreidx(bus->sih); + if (si_setcore(bus->sih, SYSMEM_CORE_ID, 0)) { + si_core_reset(bus->sih, 0, 0); + si_setcoreidx(bus->sih, save_idx); + } + DHD_ERROR(("%s: Collecting Dump after SR\n", __FUNCTION__)); if (dhdpcie_sssr_dump_get_after_sr(dhd) != BCME_OK) { DHD_ERROR(("%s: dhdpcie_sssr_dump_get_after_sr failed\n", __FUNCTION__)); @@ -15197,6 +15260,9 @@ dhdpcie_fis_dump(dhd_pub_t *dhd) dhd->sssr_dump_collected = TRUE; dhd_write_sssr_dump(dhd, SSSR_DUMP_MODE_FIS); + /* re-read socram into buffer */ + dhdpcie_get_mem_dump(bus); + return BCME_OK; } diff --git a/dhd_pktlog.c b/dhd_pktlog.c index fee33ba..9009f36 100644 --- a/dhd_pktlog.c +++ b/dhd_pktlog.c @@ -1209,8 +1209,8 @@ dhd_pktlog_dump_write_file(dhd_pub_t *dhdp) set_fs(KERNEL_DS); file_mode = O_CREAT | O_WRONLY; - w_pcap_fp = filp_open(pktlogdump_path, file_mode, 0664); - if (IS_ERR(w_pcap_fp)) { + w_pcap_fp = dhd_filp_open(pktlogdump_path, file_mode, 0664); + if (IS_ERR(w_pcap_fp) || (w_pcap_fp == NULL)) { DHD_ERROR(("%s: Couldn't open file '%s' err %ld\n", __FUNCTION__, pktlogdump_path, PTR_ERR(w_pcap_fp))); ret = BCME_ERROR; @@ -1224,14 +1224,14 @@ dhd_pktlog_dump_write_file(dhd_pub_t *dhdp) } /* Sync file from filesystem to physical media */ - ret = vfs_fsync(w_pcap_fp, 0); + ret = dhd_vfs_fsync(w_pcap_fp, 0); if (ret < 0) { DHD_ERROR(("%s(): sync pcap file error, err = %d\n", __FUNCTION__, ret)); goto fail; } fail: if (!IS_ERR(w_pcap_fp)) { - filp_close(w_pcap_fp, NULL); + dhd_filp_close(w_pcap_fp, NULL); } set_fs(old_fs); @@ -1920,6 +1920,8 @@ dhd_rtt_update_geofence_sessions_cnt(dhd_pub_t *dhd, bool incr, geofence_cfg->geofence_sessions_cnt--; } } + +exit: if (peer_addr) { WL_INFORM_MEM(("session cnt update, upd = %d, cnt = %d, cnt_bef_upd = %d, " " peer : "MACDBG", ret = %d\n", incr, geofence_cfg->geofence_sessions_cnt, @@ -1930,7 +1932,6 @@ dhd_rtt_update_geofence_sessions_cnt(dhd_pub_t *dhd, bool incr, geofence_ssn_cnt_before_upd, ret)); } -exit: return ret; } @@ -2146,7 +2147,7 @@ dhd_rtt_remove_geofence_target(dhd_pub_t *dhd, struct ether_addr *peer_addr) int err = BCME_OK; rtt_status_info_t *rtt_status; rtt_geofence_target_info_t *geofence_target_info; - int8 geofence_target_cnt, j, index = 0; + int8 geofence_target_cnt, j, index = DHD_RTT_INVALID_TARGET_INDEX; struct net_device *dev; struct bcm_cfg80211 *cfg; @@ -2165,14 +2166,15 @@ dhd_rtt_remove_geofence_target(dhd_pub_t *dhd, struct ether_addr *peer_addr) goto exit; } - /* Get the geofence_target via peer addr */ - geofence_target_info = dhd_rtt_get_geofence_target(dhd, peer_addr, &index); - if (geofence_target_info == NULL) { + /* Get the geofence_target index via peer addr */ + dhd_rtt_get_geofence_target(dhd, peer_addr, &index); + if (index == DHD_RTT_INVALID_TARGET_INDEX) { DHD_RTT(("Geofencing RTT target not found, remove request dropped\n")); err = BCME_NOTFOUND; goto exit; } + geofence_target_info = rtt_status->geofence_cfg.geofence_target_info; /* left shift all the valid entries, as we dont keep holes in list */ for (j = index; j < geofence_target_cnt; j++) { /* @@ -2180,8 +2182,8 @@ dhd_rtt_remove_geofence_target(dhd_pub_t *dhd, struct ether_addr *peer_addr) * statically allocated */ if ((j + 1) < geofence_target_cnt) { - (void)memcpy_s(&geofence_target_info[j], sizeof(geofence_target_info[j]), - &geofence_target_info[j + 1], sizeof(geofence_target_info[j + 1])); + (void)memcpy_s(&geofence_target_info[j], sizeof(rtt_geofence_target_info_t), + &geofence_target_info[j + 1], sizeof(rtt_geofence_target_info_t)); } else { /* reset the last target info */ bzero(&geofence_target_info[j], sizeof(rtt_geofence_target_info_t)); diff --git a/hnd_pktpool.c b/hnd_pktpool.c index 8938407..e973267 100644 --- a/hnd_pktpool.c +++ b/hnd_pktpool.c @@ -1170,7 +1170,7 @@ BCMPOSTTRAPFN(pktpool_avail_notify)(pktpool_t *pktp) #ifdef APP_RX /* Update freelist and avail count for a given packet pool */ void -BCMFASTPATH(pktpool_update_freelist)(pktpool_t *pktp, void *p, uint pkts_consumed) +BCMPOSTTRAPFASTPATH(pktpool_update_freelist)(pktpool_t *pktp, void *p, uint pkts_consumed) { ASSERT_FP(pktp->avail >= pkts_consumed); @@ -1172,7 +1172,7 @@ done: } void * -pktq_peek(struct pktq *pq, int *prec_out) +BCMPOSTTRAPFN(pktq_peek)(struct pktq *pq, int *prec_out) { int prec; void *p = NULL; diff --git a/include/802.11.h b/include/802.11.h index 7e9b0db..3449540 100644 --- a/include/802.11.h +++ b/include/802.11.h @@ -216,6 +216,7 @@ typedef struct dot11_action_vs_frmhdr dot11_action_vs_frmhdr_t; #define DOT11_BA_CTL_MTID 0x0002 /* multi tid BA */ #define DOT11_BA_CTL_COMPRESSED 0x0004 /* compressed bitmap */ +#define DOT11_BA_CTL_GCR 0x0008 /* GCR BAR */ #define DOT11_BA_CTL_NUMMSDU_MASK 0x0FC0 /* num msdu in bitmap mask */ #define DOT11_BA_CTL_NUMMSDU_SHIFT 6 /* num msdu in bitmap shift */ @@ -239,6 +240,14 @@ BWL_PRE_PACKED_STRUCT struct dot11_bar { } BWL_POST_PACKED_STRUCT; #define DOT11_BAR_LEN 4 /* BAR frame payload length */ +/** GCR BAR frame payload */ +BWL_PRE_PACKED_STRUCT struct dot11_gcr_bar { + uint16 bar_control; /* BAR Control */ + uint16 seqnum; /* Starting Sequence control */ + struct ether_addr gcr; /* GCR address */ +} BWL_POST_PACKED_STRUCT; +#define DOT11_GCR_BAR_LEN 10u /* GCR BAR frame payload length */ + #define DOT11_BA_BITMAP_LEN 128 /* bitmap length */ #define DOT11_BA_CMP_BITMAP_LEN 8 /* compressed bitmap length */ /** BA frame payload */ @@ -3993,7 +4002,9 @@ typedef struct dot11_mprep dot11_mprep_t; /* HT-SIG1 */ #define HT_SIG1_MCS_MASK 0x00007F #define HT_SIG1_CBW 0x000080 +#define HT_SIG1_CBW_SHIFT 7u #define HT_SIG1_HT_LENGTH 0xFFFF00 +#define HT_SIG1_HT_LENGTH_SHIFT 8u /* HT-SIG2 */ #define HT_SIG2_SMOOTHING 0x000001 @@ -5219,6 +5230,7 @@ typedef struct dot11_ftm_ranging_ndpa dot11_ftm_ranging_ndpa_t; #define DOT11_NDPA_TYPE_VHT 0x00 #define DOT11_NDPA_TYPE_RANGING 0x01 #define DOT11_NDPA_TYPE_HE 0x02 +#define DOT11_NPDA_TOKEN_SHIFT 2u #define DOT11_FTM_ERR_NOT_CONT_OFFSET 1 #define DOT11_FTM_ERR_NOT_CONT_MASK 0x80 @@ -5890,11 +5902,18 @@ BWL_PRE_PACKED_STRUCT struct supp_op_classes_ie { } BWL_POST_PACKED_STRUCT; typedef struct supp_op_classes_ie supp_op_classes_ie_t; -/* Transition mode (bit number) */ -#define TRANSISION_MODE_WPA3_PSK 0u -#define TRANSITION_MODE_SAE_PK 1u -#define TRANSITION_MODE_WPA3_ENTERPRISE 2u -#define TRANSITION_MODE_ENHANCED_OPEN 3u +/* WPA3 Transition Mode bits */ +#define TRANSISION_MODE_WPA3_PSK BCM_BIT(0) +#define TRANSITION_MODE_WPA3_PSK BCM_BIT(0) +#define TRANSITION_MODE_SAE_PK BCM_BIT(1) +#define TRANSITION_MODE_WPA3_ENTERPRISE BCM_BIT(2) +#define TRANSITION_MODE_ENHANCED_OPEN BCM_BIT(3) + +#define TRANSITION_MODE_SUPPORTED_MASK (\ + TRANSITION_MODE_WPA3_PSK | \ + TRANSITION_MODE_SAE_PK | \ + TRANSITION_MODE_WPA3_ENTERPRISE | \ + TRANSITION_MODE_ENHANCED_OPEN) /* This marks the end of a packed structure section. */ #include <packed_section_end.h> diff --git a/include/bcmerror.h b/include/bcmerror.h index 0d6a4e6..85798c7 100644 --- a/include/bcmerror.h +++ b/include/bcmerror.h @@ -515,6 +515,72 @@ enum { /* signature package is invalid */ BCM_FWSIGN_E_PACKAGE_INVALID = -4121, + /* chip info mismatch */ + BCM_FWSIGN_E_CHIP_INFO_MISMATCH = -4122, + + /* key use is not valid */ + BCM_FWSIGN_E_KEY_USE_NOT_VALID = -4123, + + /* fw tag type invalid */ + BCM_FWSIGN_E_TAG_TYPE_INVALID = -4124, + + /* fwenc header invalid */ + BCM_FWSIGN_E_FWENC_HDR_INVALID = -4125, + + /* firmware encryption header version mismatch */ + BCM_FWSIGN_E_FWENC_HDR_VERSION = -4126, + + /* firmware encryption cipher type not supported */ + BCM_FWSIGN_E_FWENC_CIPHER_TYPE_UNSUPPORTED = -4127, + + /* firmware encryption tlv type not supported */ + BCM_FWSIGN_E_FWENC_TLV_TYPE_UNSUPPORTED = -4128, + + /* firmware encryption invalid kdf info */ + BCM_FWSIGN_E_FWENC_INVALID_KDFINFO = -4129, + + /* firmware encryption invalid ec group type length */ + BCM_FWSIGN_E_FWENC_INVALID_ECG_TYPE_LEN = -4130, + + /* firmware encryption invalid epub */ + BCM_FWSIGN_E_FWENC_INVALID_EPUB = -4131, + + /* firmware encryption invalid iv */ + BCM_FWSIGN_E_FWENC_INVALID_IV = -4132, + + /* firmware encryption invalid aad */ + BCM_FWSIGN_E_FWENC_INVALID_AAD = -4133, + + /* firmware encryption invalid ROM key */ + BCM_FWSIGN_E_FWENC_INVALID_ROMKEY = -4134, + + /* firmware encryption invalid sysmem key */ + BCM_FWSIGN_E_FWENC_INVALID_SYSMEMKEY = -4135, + + /* firmware encryption invalid OTP key */ + BCM_FWSIGN_E_FWENC_INVALID_OTPKEY = -4136, + + /* firmware encryption key unwrap fail */ + BCM_FWSIGN_E_FWENC_KEY_UNWRAP_FAIL = -4137, + + /* firmware encryption generate share secret fail */ + BCM_FWSIGN_E_FWENC_GEN_SECRET_FAIL = -4138, + + /* firmware encryption symmetric key derivation fail */ + BCM_FWSIGN_E_FWENC_KEY_DERIVATION_FAIL = -4139, + + /* firmware encryption RNG read fail */ + BCM_FWSIGN_E_FWENC_RNG_FAIL = -4140, + + /* firmware encryption MAC tampered during decryption */ + BCM_FWSIGN_E_FWENC_MAC_TAMPERED = -4141, + + /* firmware encryption decryption failed */ + BCM_FWSIGN_E_FWENC_DECRYPT_FAIL = -4142, + + /* firmware encryption decryption in progress */ + BCM_FWSIGN_E_FWENC_DECRYPT_IN_PROGRESS = -4143, + /* last error */ BCM_FWSIGN_E_LAST = -5119 }; diff --git a/include/bcmmsgbuf.h b/include/bcmmsgbuf.h index d9177d7..eef8028 100644 --- a/include/bcmmsgbuf.h +++ b/include/bcmmsgbuf.h @@ -502,6 +502,7 @@ typedef struct pcie_dma_xfer_params { #define BCMPCIE_FLOW_RING_INTF_HP2P 0x01u /* bit0 */ #define BCMPCIE_FLOW_RING_OPT_EXT_TXSTATUS 0x02u /* bit1 */ #define BCMPCIE_FLOW_RING_INTF_MESH 0x04u /* bit2, identifies the mesh flow ring */ +#define BCMPCIE_FLOW_RING_INTF_LLW 0x08u /* bit3, identifies the llw flow ring */ /** Complete msgbuf hdr for flow ring update from host to dongle */ typedef struct tx_flowring_create_request { diff --git a/include/bcmutils.h b/include/bcmutils.h index 0a44f47..715d246 100644 --- a/include/bcmutils.h +++ b/include/bcmutils.h @@ -209,10 +209,14 @@ extern uint pkttotlen_no_sfhtoe_hdr(osl_t *osh, void *p, uint toe_hdr_len); #define PKTPRIO_DSCP 0x800u /* DSCP prio found */ /* DSCP type definitions (RFC4594) */ +/* DF: Standard (RFC2474) */ +#define DSCP_DF 0x00u /* AF1x: High-Throughput Data (RFC2597) */ #define DSCP_AF11 0x0Au #define DSCP_AF12 0x0Cu #define DSCP_AF13 0x0Eu +/* CS1: Low-Priority Data (RFC3662) */ +#define DSCP_CS1 0x08u /* AF2x: Low-Latency Data (RFC2597) */ #define DSCP_AF21 0x12u #define DSCP_AF22 0x14u @@ -225,6 +229,14 @@ extern uint pkttotlen_no_sfhtoe_hdr(osl_t *osh, void *p, uint toe_hdr_len); #define DSCP_AF33 0x1Eu /* CS3: Broadcast Video (RFC2474) */ #define DSCP_CS3 0x18u +/* AF4x: Multimedia Conferencing (RFC2597) */ +#define DSCP_AF41 0x22u +#define DSCP_AF42 0x24u +#define DSCP_AF43 0x26u +/* CS4: Real-Time Interactive (RFC2474) */ +#define DSCP_CS4 0x20u +/* CS5: Signaling (RFC2474) */ +#define DSCP_CS5 0x28u /* VA: VOCIE-ADMIT (RFC5865) */ #define DSCP_VA 0x2Cu /* EF: Telephony (RFC3246) */ diff --git a/include/epivers.h b/include/epivers.h index a10686f..8180db7 100644 --- a/include/epivers.h +++ b/include/epivers.h @@ -27,25 +27,25 @@ #define EPI_MINOR_VERSION 10 -#define EPI_RC_NUMBER 370 +#define EPI_RC_NUMBER 384 #define EPI_INCREMENTAL_NUMBER 0 #define EPI_BUILD_NUMBER 0 -#define EPI_VERSION 101, 10, 370, 0 +#define EPI_VERSION 101, 10, 384, 0 -#define EPI_VERSION_NUM 0x650a1720 +#define EPI_VERSION_NUM 0x650a1800 -#define EPI_VERSION_DEV 101.10.370 +#define EPI_VERSION_DEV 101.10.384 /* Driver Version String, ASCII, 32 chars max */ #if defined (WLTEST) -#define EPI_VERSION_STR "101.10.370 (wlan=r894296 WLTEST)" +#define EPI_VERSION_STR "101.10.384 (wlan=r896154 WLTEST)" #elif (defined (BCMDBG_ASSERT) && !defined (BCMDBG_ASSERT_DISABLED)) -#define EPI_VERSION_STR "101.10.370 (wlan=r894296 ASSRT)" +#define EPI_VERSION_STR "101.10.384 (wlan=r896154 ASSRT)" #else -#define EPI_VERSION_STR "101.10.370 (wlan=r894296)" +#define EPI_VERSION_STR "101.10.384 (wlan=r896154)" #endif /* BCMINTERNAL */ #endif /* _epivers_h_ */ diff --git a/include/ethernet.h b/include/ethernet.h index 302f1a5..5f9a8c1 100644 --- a/include/ethernet.h +++ b/include/ethernet.h @@ -174,6 +174,14 @@ BWL_PRE_PACKED_STRUCT struct ether_addr { (((const uint16 *)(a))[6] ^ ((const uint16 *)(b))[6])) #endif /* DONGLEBUILD && __ARM_ARCH_7A__ */ +#define eacmp_nogrp(a, b) \ + (((((const uint8 *)(a))[0] & 0x0e) ^ (((const uint8 *)(b))[0] & 0x0e)) | \ + (((const uint8 *)(a))[1] ^ ((const uint8 *)(b))[1]) | \ + (((const uint8 *)(a))[2] ^ ((const uint8 *)(b))[2]) | \ + (((const uint8 *)(a))[3] ^ ((const uint8 *)(b))[3]) | \ + (((const uint8 *)(a))[4] ^ ((const uint8 *)(b))[4]) | \ + (((const uint8 *)(a))[5] ^ ((const uint8 *)(b))[5])) + #define ether_cmp(a, b) eacmp(a, b) /* copy an ethernet address - assumes the pointers can be referenced as shorts */ diff --git a/include/event_log_tag.h b/include/event_log_tag.h index a5d735d..ea0700c 100644 --- a/include/event_log_tag.h +++ b/include/event_log_tag.h @@ -484,8 +484,13 @@ #define EVENT_LOG_TAG_PKTFLTR_TRACE 390 #define EVENT_LOG_TAG_PKTFLTR_WARN 391 #define EVENT_LOG_TAG_PKTFLTR_ERROR 392 + +/* LLW */ +#define EVENT_LOG_TAG_LLW_ERR 393 +#define EVENT_LOG_TAG_LLW_INFO 394 + /* EVENT_LOG_TAG_MAX = Set to the same value of last tag, not last tag + 1 */ -#define EVENT_LOG_TAG_MAX 392 +#define EVENT_LOG_TAG_MAX 394 typedef enum wl_el_set_type_def { EVENT_LOG_SET_TYPE_DEFAULT = 0, /* flush the log buffer when it is full - Default option */ diff --git a/include/linux_osl.h b/include/linux_osl.h index e87c0c6..0de0ee5 100644 --- a/include/linux_osl.h +++ b/include/linux_osl.h @@ -28,10 +28,21 @@ #define DECLSPEC_ALIGN(x) __attribute__ ((aligned(x))) /* Linux Kernel: File Operations: start */ +#ifdef DHD_SUPPORT_VFS_CALL extern void * osl_os_open_image(char * filename); -extern int osl_os_get_image_block(char * buf, int len, void * image); extern void osl_os_close_image(void * image); +extern int osl_os_get_image_block(char * buf, int len, void * image); extern int osl_os_image_size(void *image); +#else +static INLINE void * osl_os_open_image(char * filename) + { return NULL; } +static INLINE void osl_os_close_image(void * image) + { return; } +static INLINE int osl_os_get_image_block(char * buf, int len, void * image) + { return 0; } +static INLINE int osl_os_image_size(void *image) + { return 0; } +#endif /* DHD_SUPPORT_VFS_CALL */ /* Linux Kernel: File Operations: end */ #ifdef BCMDRIVER diff --git a/include/wlioctl.h b/include/wlioctl.h index 94ee286..c860ff5 100644 --- a/include/wlioctl.h +++ b/include/wlioctl.h @@ -1801,6 +1801,10 @@ typedef enum sup_auth_status { WLC_SUP_KEYXCHANGE_PREP_G2 /**< Preparing to send handshake msg G2 */ } sup_auth_status_t; +#define WLC_SUP_TD_POLICY_XTLV_ID 0x1u +#define WLC_SUP_TD_POLICY_XTLV_ELEM_SIZE 0x4u /* 4B aligned */ +#define WLC_SUP_TD_POLICY_XTLV_SIZE (BCM_XTLV_HDR_SIZE + WLC_SUP_TD_POLICY_XTLV_ELEM_SIZE) + typedef struct wl_wsec_key { uint32 index; /**< key index */ uint32 len; /**< key length */ @@ -3225,6 +3229,7 @@ typedef struct { #define WL_TXPPR_LENGTH (sizeof(wl_txppr_t)) #define TX_POWER_T_VERSION 45 #define TX_POWER_T_VERSION_V2 46 +#define TX_POWER_T_VERSION_V3 47 /* curpower ppr types */ enum { @@ -3486,6 +3491,7 @@ typedef struct wl_mws_ocl_override { #define OCL_DISABLED_IDLE_TSSICAL 0x200 #define OCL_DISABLED_TONE 0x400 /* Disabled if the tone is active */ #define OCL_DISABLED_NOISECAL 0x800 /* Disabled if the noise cal is active */ +#define OCL_DISABLED_INIT 0x1000 /* Disabled during phy init */ /* Bits for hw_status */ #define OCL_HWCFG 0x01 /* State of OCL config bit in phy HW */ @@ -9561,6 +9567,52 @@ typedef BWL_PRE_PACKED_STRUCT struct { int8 antgain[3]; /**< Ant gain for each band - from SROM */ uint8 pprdata[1]; /**< ppr serialization buffer */ } BWL_POST_PACKED_STRUCT tx_pwr_rpt_v2_t; + +#define WL_TPC_MAX_BW_TX_PWR_LEN 8u +#define WL_TPC_MAX_RU_TX_PWR_LEN 8u +#define WL_TPE_MAX_TX_PWRS_LEN 16u + +typedef BWL_PRE_PACKED_STRUCT struct wl_tpc_bw_txpwr { + wl_tx_bw_t bw; + int8 txpwr; +} BWL_POST_PACKED_STRUCT wl_tpc_bw_txpwr_t; + +typedef BWL_PRE_PACKED_STRUCT struct wl_tpc_ru_txpwr { + int ru; /* RU of wl_he_rate_type_t type */ + int8 txpwr; +} BWL_POST_PACKED_STRUCT wl_tpc_ru_txpwr_t; + +typedef BWL_PRE_PACKED_STRUCT struct { + uint32 flags; + chanspec_t chanspec; /**< txpwr report for this channel */ + chanspec_t local_chanspec; /**< channel on which we are associated */ + uint8 local_max; /**< local max according to the AP */ + uint8 local_constraint; /**< local constraint according to the AP */ + int8 pad[2]; /**< unused */ + uint8 rf_cores; /**< count of RF Cores being reported */ + uint8 est_Pout[4]; /**< Latest tx power out estimate per RF chain */ + uint8 est_Pout_act[4]; /**< Latest tx power out estimate per RF chain w/o adjustment */ + uint8 est_Pout_cck; /**< Latest CCK tx power out estimate */ + uint8 tx_power_max[4]; /**< Maximum target power among all rates */ + uint32 tx_power_max_rate_ind[4]; /**< Index of the rate with the max target power */ + int8 sar; /**< SAR limit for display by wl executable */ + int8 channel_bandwidth; /**< 20, 40 or 80 MHz bandwidth? */ + uint8 version; /**< Version of the data format wlu <--> driver */ + uint8 display_core; /**< Displayed curpower core */ + int8 target_offsets[4]; /**< Target power offsets for current rate per core */ + uint32 last_tx_ratespec; /**< Ratespec for last transmition */ + uint32 user_target; /**< user limit */ + uint32 ppr_len; /**< length of each ppr serialization buffer */ + int8 SARLIMIT[MAX_STREAMS_SUPPORTED]; + int8 antgain[3]; /**< Ant gain for each band - from SROM */ + uint8 tpe_txpwrs_len; /**< # max txpwrs rcvd in TPE elem */ + int8 tpe_txpwrs[WL_TPE_MAX_TX_PWRS_LEN]; /**< TPE parsed max txpwrs */ + uint8 sb_txpwrs_len; /**< No of TPE sb_txpwrs present */ + wl_tpc_bw_txpwr_t sb_txpwrs[WL_TPC_MAX_BW_TX_PWR_LEN]; /**< TPE Subband max txpwrs */ + uint8 ru_txpwrs_len; /**< No of TPE RU txpwrs present */ + wl_tpc_ru_txpwr_t ru_txpwrs[WL_TPC_MAX_RU_TX_PWR_LEN]; /**< TPE RU max txpwrs */ + uint8 pprdata[1]; /**< ppr serialization buffer */ +} BWL_POST_PACKED_STRUCT tx_pwr_rpt_v3_t; #include <packed_section_end.h> typedef struct tx_pwr_ru_rate_info { @@ -16135,7 +16187,6 @@ typedef uint64 wl_ftm_session_mask_t; /* flags relevant to MC sessions */ #define FTM_MC_CONFIG_MASK \ - (FTM_COMMON_CONFIG_MASK) | \ (WL_FTM_SESSION_FLAG_AUTO_VHTACK \ | WL_FTM_SESSION_FLAG_MBURST_NODELAY \ | WL_FTM_SESSION_FLAG_ASAP_CAPABLE \ @@ -16151,13 +16202,12 @@ typedef uint64 wl_ftm_session_mask_t; /* flags relevant to NTB sessions */ #define FTM_NTB_CONFIG_MASK \ - (FTM_COMMON_CONFIG_MASK) | \ (WL_FTM_SESSION_FLAG_R2I_TOA_PHASE_SHIFT \ | WL_FTM_SESSION_FLAG_I2R_TOA_PHASE_SHIFT \ | WL_FTM_SESSION_FLAG_I2R_IMMEDIATE_RPT \ | WL_FTM_SESSION_FLAG_R2I_IMMEDIATE_RPT) -/* flages relevant to TB sessions. To be expanded */ +/* flags relevant to TB sessions. To be expanded */ #define FTM_TB_CONFIG_MASK (FTM_NTB_CONFIG_MASK) /** time units - mc supports up to 0.1ns resolution */ @@ -21011,6 +21061,7 @@ enum wl_otp_xtlv_id { WL_OTP_XTLV_SBOOT_WAFER_Y = 25u, /* Chip wafer Y 9 bits */ WL_OTP_XTLV_SBOOT_UNLOCK_HASH_VAL = 26u, /* Unlock Hash Val 128 bits */ WL_OTP_XTLV_SBOOT_PRODUCTION_CHIP = 27u, /* Production chip bit */ + WL_OTP_XTLV_SBOOT_ENCRYPTION_KEY = 28u, /* AES wrapped fw encryption key 320 bits */ }; #define WL_LEAKY_AP_STATS_GT_TYPE 0 @@ -23410,6 +23461,19 @@ typedef struct wl_ulmu_disable_stats { uint16 avg_latency; /* Avg latency by AP to re-act for UL OFDMA disable request (ms) */ } wl_ulmu_disable_stats_v1_t; +#define WL_TPE_TXPWR_CONFIG_VERSION_1 1u +#define WL_TPE_TXPWR_MAX_LEN 8u + +typedef struct wl_tpe_txpwr_config { + uint16 version; + uint16 len; + uint8 idx; /* Index of profile */ + uint8 cat; /* Transmit Power Info category */ + uint8 intr; /* Transmit Power Info Interpretation */ + uint8 cnt; /* Transmit Power Info count */ + int8 txpwr[WL_TPE_TXPWR_MAX_LEN]; /* Maximum TX power */ +} wl_tpe_txpwr_config_v1_t; + /* sub-xtlv IDs within WL_STATS_XTLV_WL_SLICE_TX_HISTOGRAMS */ enum wl_tx_histogram_id { WL_TX_HIST_TXQ_ID = 1, @@ -24761,6 +24825,10 @@ enum { BCM_TRACE_E_MSCH = 2, BCM_TRACE_E_SC = 3, BCM_TRACE_E_SCAN = 4, + BCM_TRACE_E_ASSOC = 5, + BCM_TRACE_E_SCAN_STATE = 6, + BCM_TRACE_E_RX_STALL = 7, + BCM_TRACE_E_TX_STALL = 8, BCM_TRACE_E_LAST }; @@ -24811,4 +24879,75 @@ typedef struct wl_auth_start_evt { uint32 key_mgmt_suite; uint8 opt_tlvs[]; } wl_auth_start_evt_t; + +/* Additional header pushed to the logged mgmt frame in aml(assoc mgmt frame logger) */ +typedef struct wl_aml_header_v1 { + uint16 version; /* Header version, now 1 */ + uint16 length; /* frame length excluding this header */ + uint16 flags; /* flag to indicate tx/rx, acked/noack and others */ + uint8 pad[2]; /* pad bytes for align */ +} wl_aml_header_v1_t; + +/* Version for aml header */ +#define WL_AML_HEADER_VERSION 1u + +/* Flags for aml header */ +#define WL_AML_F_DIRECTION 0x0001 /* This flag indicates this is Tx mgmt, otherwise Rx */ +#define WL_AML_F_ACKED 0x0002 /* This flag indicates the frame is acked */ + +/* Version for IOVAR 'aml' */ +#define WL_AML_IOV_MAJOR_VER 1u +#define WL_AML_IOV_MINOR_VER 0u +#define WL_AML_IOV_MAJOR_VER_SHIFT 8u +#define WL_AML_IOV_VERSION \ + ((WL_AML_IOV_MAJOR_VER << WL_AML_IOV_MAJOR_VER_SHIFT) | WL_AML_IOV_MINOR_VER) + +/* Common header for IOVAR 'aml' */ +typedef struct wl_aml_iov_cmnhdr { + uint16 ver; /* IOVAR cmd structure version */ + uint16 len; /* IOVAR cmd structure total len (cmnhdr + following subcmd) */ + uint16 subcmd; /* IOVAR subcmd */ + uint8 pad[2]; +} wl_aml_iov_cmnhdr_t; + +/* IOVAR 'aml' data structure, cmn header is followed by subcmd structure */ +typedef struct wl_aml_iovar { + wl_aml_iov_cmnhdr_t hdr; + uint32 data[0]; +} wl_aml_iovar_t; + +/* IOVAR 'aml' subcmd list */ +enum wl_aml_subcmd_ids { + WL_AML_SUBCMD_ENABLE = 1, /* Enable/disable aml feature */ + WL_AML_SUBCMD_LAST +}; + +/* IOVAR 'aml' subcmd structure for uint32 data + * Subcmd 'enable' uses this structure + */ +typedef struct wl_aml_iov_uint_data { + uint32 val; +} wl_aml_iov_uint_data_t; + +/* IOVAR 'aml enable' subcmd bit numbers + * wl_aml_iov_uint_data.val is popluated with following bits + */ +enum wl_aml_cmd_enable_bitnums { + WL_AML_ASSOC_ENABLE = 0, /* Logging for association */ + WL_AML_ROAM_ENABLE = 1, /* Logging for roaming */ + WL_AML_ENABLE_LAST +}; + +/* Snapshot of various timestamps */ +#define WL_TIMESTAMP_VERSION_1 1 +typedef struct wl_timestamps_v1 { + uint16 version; /**< structure version */ + uint16 length; /**< length of this struct */ + uint64 cpu_cycles; /**< CPU Cycle count */ + uint64 ptm; /**< Local PTM master timestamp in nano seconds */ + uint64 pmu_timer; /**< Legacy PMU timer in micsoseconds */ + uint32 tsf_main; /**< Main slice TSF */ + uint32 tsf_aux; /**< Aux slice TSF */ + uint32 tsf_scan; /**< Scan core TSF */ +} wl_timestamps_v1_t; #endif /* _wlioctl_h_ */ diff --git a/include/wlioctl_defs.h b/include/wlioctl_defs.h index f0e8315..e770da2 100644 --- a/include/wlioctl_defs.h +++ b/include/wlioctl_defs.h @@ -1361,6 +1361,8 @@ #define WL_TX_POWER_F_TXCAP 0x200 #define WL_TX_POWER_F_HE 0x400 #define WL_TX_POWER_F_RU_RATE 0x800 +#define WL_TX_POWER_TPE_PSD 0x1000 +#define WL_TX_POWER_TPE_LOC 0x2000 /* Message levels */ #define WL_ERROR_VAL 0x00000001 @@ -1558,11 +1560,19 @@ * It is preserved only for compatibility with older branches that use it */ #ifdef WL_BAND6G +#ifdef WL_BAND5P9G +#ifdef WL11AC_80P80 +#define WL_NUMCHANSPECS 466 +#else +#define WL_NUMCHANSPECS 370 +#endif +#else #ifdef WL11AC_80P80 #define WL_NUMCHANSPECS 446 #else #define WL_NUMCHANSPECS 350 #endif +#endif /* WL_BAND5P9G */ #else #if defined(WL11AC_80P80) #define WL_NUMCHANSPECS 206 diff --git a/linux_osl.c b/linux_osl.c index 36009d5..c49c69c 100644 --- a/linux_osl.c +++ b/linux_osl.c @@ -1697,6 +1697,7 @@ osl_rand(void) return rand; } +#ifdef DHD_SUPPORT_VFS_CALL /* Linux Kernel: File Operations: start */ void * osl_os_open_image(char *filename) @@ -1761,6 +1762,7 @@ osl_os_image_size(void *image) } return len; } +#endif /* DHD_SUPPORT_VFS_CALL */ /* Linux Kernel: File Operations: end */ @@ -1918,7 +1920,11 @@ osl_timer_del(osl_t *osh, osl_timer_t *t) int kernel_read_compat(struct file *file, loff_t offset, char *addr, unsigned long count) { +#ifdef DHD_SUPPORT_VFS_CALL return (int)kernel_read(file, addr, (size_t)count, &offset); +#else + return 0; +#endif /* DHD_SUPPORT_VFS_CALL */ } #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) */ @@ -2525,6 +2525,7 @@ BCMPOSTTRAPFN(si_gci_chipcontrol)(si_t *sih, uint reg, uint32 mask, uint32 val) si_corereg(sih, GCI_CORE_IDX(sih), GCI_OFFSETOF(sih, gci_indirect_addr), ~0, reg); return si_corereg(sih, GCI_CORE_IDX(sih), GCI_OFFSETOF(sih, gci_chipctrl), mask, val); } +#endif /* !defined(BCMDONGLEHOST) */ /* Read the gci chip status register indexed by 'reg' */ uint32 @@ -2541,7 +2542,6 @@ BCMPOSTTRAPFN(si_gci_chipstatus)(si_t *sih, uint reg) /* setting mask and value to '0' to use si_corereg for read only purpose */ return si_corereg(sih, GCI_CORE_IDX(sih), GCI_OFFSETOF(sih, gci_chipsts), 0, 0); } -#endif /* !defined(BCMDONGLEHOST) */ uint16 si_chipid(const si_t *sih) diff --git a/wl_android.c b/wl_android.c index 8cbada9..34b64e8 100644 --- a/wl_android.c +++ b/wl_android.c @@ -268,8 +268,10 @@ #define CMD_GETOKCMODE "GETOKCMODE" #define CMD_SETOKCMODE "SETOKCMODE" -#define CMD_OKC_SET_PMK "SET_PMK" -#define CMD_OKC_ENABLE "OKC_ENABLE" +#define CMD_OKC_SET_PMK "SET_PMK" +#define CMD_OKC_ENABLE "OKC_ENABLE" + +#define CMD_SET_5G160 "CONFIG_5G160" typedef struct android_wifi_reassoc_params { unsigned char bssid[18]; @@ -617,6 +619,27 @@ static const wl_natoe_sub_cmd_t natoe_cmd_list[] = { #define CMD_PCIE_IRQ_CORE "PCIE_IRQ_CORE" #endif /* SET_PCIE_IRQ_CPU_CORE */ +#ifdef WLADPS_PRIVATE_CMD +#define CMD_SET_ADPS "SET_ADPS" +#define CMD_GET_ADPS "GET_ADPS" +#ifdef WLADPS_ENERGY_GAIN +#define CMD_GET_GAIN_ADPS "GET_GAIN_ADPS" +#define CMD_RESET_GAIN_ADPS "RESET_GAIN_ADPS" +#ifndef ADPS_GAIN_2G_PM0_IDLE +#define ADPS_GAIN_2G_PM0_IDLE 0 +#endif +#ifndef ADPS_GAIN_5G_PM0_IDLE +#define ADPS_GAIN_5G_PM0_IDLE 0 +#endif +#ifndef ADPS_GAIN_2G_TX_PSPOLL +#define ADPS_GAIN_2G_TX_PSPOLL 0 +#endif +#ifndef ADPS_GAIN_5G_TX_PSPOLL +#define ADPS_GAIN_5G_TX_PSPOLL 0 +#endif +#endif /* WLADPS_ENERGY_GAIN */ +#endif /* WLADPS_PRIVATE_CMD */ + #ifdef DHD_PKT_LOGGING #define CMD_PKTLOG_FILTER_ENABLE "PKTLOG_FILTER_ENABLE" #define CMD_PKTLOG_FILTER_DISABLE "PKTLOG_FILTER_DISABLE" @@ -2951,6 +2974,75 @@ wl_android_set_pmk(struct net_device *dev, char *command, int total_len) return error; } +#define BW_5G160_DISABLE 0x7u +#define BW_5G160_ENABLE 0xFu +static int +wl_android_config_5g160(struct net_device *dev, char *command) +{ + int ret = 0; + u32 enable = 0; + wl_bw_cap_t cap; + char buf[WLC_IOCTL_SMLEN] = {0}; + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); + s32 iftype; + u32 wlc_up = 0; + + bzero(&cap, sizeof(wl_bw_cap_t)); + enable = command[strlen(CMD_SET_5G160) + 1] - '0'; + + if (bcmcfg_to_prmry_ndev(cfg) != dev) { + WL_ERR(("band config on non-sta interface\n")); + return -EINVAL; + } + + if (wl_get_drv_status(cfg, CONNECTED, dev)) { + + /* Check whether we can do wl down */ + iftype = wl_cfg80211_get_sec_iface(cfg); + if (iftype != WL_IFACE_NOT_PRESENT) { + /* Concurrent mode. Skip bw setting. */ + WL_ERR(("concurrent iface present :%d\n", iftype)); + return -ENOTSUPP; + } + + /* If STA is connected, disassoc before band change */ + wl_cfg80211_disassoc(dev, WLAN_REASON_DEAUTH_LEAVING); + } + + cap.band = WLC_BAND_5G; + if (enable) { + cap.bw_cap = BW_5G160_ENABLE; + } else { + cap.bw_cap = BW_5G160_DISABLE; + } + + /* bw_cap is down restricted */ + ret = wldev_ioctl_set(dev, WLC_DOWN, &wlc_up, sizeof(wlc_up)); + if (ret) { + WL_ERR(("%s: WLC_DOWN failed: code: %d\n", __func__, ret)); + return ret; + } + + ret = wldev_iovar_setbuf(dev, "bw_cap", &cap, sizeof(wl_bw_cap_t), + buf, sizeof(buf), NULL); + if (ret) { + WL_ERR(("Failed to %s 5g160, error = %d\n", + enable ? "enable" : "disable", ret)); + } else { + WL_INFORM(("bw_cap (0x%x) set successfully!\n", cap.bw_cap)); + } + + /* fall through to set wlc up */ + wlc_up = 1; + ret = wldev_ioctl_set(dev, WLC_UP, &wlc_up, sizeof(wlc_up)); + if (ret) { + WL_ERR(("%s: WLC_UP failed: code: %d\n", __func__, ret)); + return ret; + } + + return ret; +} + static int wl_android_okc_enable(struct net_device *dev, char *command) { @@ -6191,7 +6283,10 @@ wl_android_get_freq_list_chanspecs(struct net_device *ndev, wl_uint32_list_t *li int i = 0; char *pcmd, *token; int len = buflen; - uint16 channel = 0; + u32 freq_bands = 0; +#ifdef WL_6G_BAND + struct bcm_cfg80211 *cfg = wl_get_cfg(ndev); +#endif /* WL_6G_BAND */ pcmd = bcmstrstr(cmd_str, FREQ_STR); pcmd += strlen(FREQ_STR); @@ -6209,7 +6304,10 @@ wl_android_get_freq_list_chanspecs(struct net_device *ndev, wl_uint32_list_t *li /* Convert chanspec from frequency */ if ((freq > 0) && ((chanspec = wl_freq_to_chanspec(freq)) != INVCHANSPEC)) { - WL_DBG(("Adding chanspec in list : 0x%x at the index %d\n", chanspec, i)); + WL_DBG(("%s:Adding chanspec in list : 0x%x at the index %d\n", + __FUNCTION__, chanspec, i)); + /* mark all the bands found */ + freq_bands |= CHSPEC_TO_WLC_BAND(CHSPEC_BAND(chanspec)); list->element[i] = chanspec; len -= sizeof(list->element[i]); i++; @@ -6229,6 +6327,7 @@ wl_android_get_freq_list_chanspecs(struct net_device *ndev, wl_uint32_list_t *li } #endif /* WL_5G_SOFTAP_ONLY_ON_DEF_CHAN */ } + WL_DBG(("** freq_bands=0x%x\n", freq_bands)); } list->count = i; @@ -6239,24 +6338,54 @@ wl_android_get_freq_list_chanspecs(struct net_device *ndev, wl_uint32_list_t *li * check with the highest band entry. */ chanspec = list->element[i-1]; - if (CHSPEC_BAND(chanspec) == sta_acs_band) { - /* softap request is for same band. Use SCC - * Convert sta channel to freq - */ - freq = wl_channel_to_frequency(sta_channel, sta_acs_band); - list->element[0] = - wl_freq_to_chanspec(freq); - channel = wf_chspec_ctlchan((chanspec_t)list->element[0]); - WL_INFORM_MEM(("Softap on same band as STA." - "Use SCC.freq = %d, chanspec:0x%x, channel = %d\n", - freq, chanspec, channel)); - } else { - list->element[0] = chanspec; - WL_INFORM_MEM(("RSDB case chanspec:0x%x\n", chanspec)); + if (sta_acs_band == WL_CHANSPEC_BAND_2G) { +#ifdef WL_6G_BAND + if ((freq_bands & WLC_BAND_6G) && cfg->band_6g_supported) { + list->element[0] = wl_freq_to_chanspec(APCS_DEFAULT_6G_FREQ); + } else +#endif /* WL_6G_BAND */ + if (freq_bands & WLC_BAND_5G) { + list->element[0] = wl_freq_to_chanspec(APCS_DEFAULT_5G_FREQ); + } else { + freq = wl_channel_to_frequency(sta_channel, sta_acs_band); + list->element[0] = wl_freq_to_chanspec(freq); + WL_INFORM_MEM(("Softap on same band as STA." + "Use SCC chanspec:0x%x\n", + list->element[0])); + } + } else if (sta_acs_band == WL_CHANSPEC_BAND_5G) { + if (freq_bands & WLC_BAND_5G) { + if (sta_channel == APCS_DEFAULT_5G_CH) { + list->element[0] = + wl_freq_to_chanspec(APCS_DEFAULT_5G_FREQ); + } else { + list->element[0] = + wl_freq_to_chanspec(APCS_DEFAULT_2G_FREQ); + } + } else { + list->element[0] = wl_freq_to_chanspec(APCS_DEFAULT_2G_FREQ); + } + } else +#ifdef WL_6G_BAND + if (sta_acs_band == WL_CHANSPEC_BAND_6G) { + if ((freq_bands & WLC_BAND_6G) && cfg->band_6g_supported) { + freq = wl_channel_to_frequency(sta_channel, sta_acs_band); + list->element[0] = wl_freq_to_chanspec(freq); + WL_INFORM_MEM(("Softap on same band as STA." + "Use SCC chanspec:0x%x\n", + list->element[0])); + } else + { + list->element[0] = wl_freq_to_chanspec(APCS_DEFAULT_2G_FREQ); + } + } else +#endif /* WL_6G_BAND */ + { + WL_ERR(("ACS: Invalid sta acs band: sta_acs_band = 0x%x\n", sta_acs_band)); + return BCME_ERROR; } - list->count = 1; - return ret; } + list->count = 1; return ret; } @@ -6635,44 +6764,68 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str, sta_band = WL_GET_BAND(sta_channel); if (sta_channel && (band != WLC_BAND_INVALID)) { switch (sta_band) { - case (WLC_BAND_5G): + case (WLC_BAND_5G): { + if ((sta_channel == APCS_DEFAULT_5G_CH) && + (band == WLC_BAND_5G || band == WLC_BAND_AUTO)) { + /* SCC is allowed only for DEF_5G Channel */ + channel = sta_channel; + acs_band = wl_cfg80211_get_acs_band(sta_band); + } else { + channel = APCS_DEFAULT_2G_CH; + acs_band = wl_cfg80211_get_acs_band(WLC_BAND_2G); + } + break; + } #ifdef WL_6G_BAND case (WLC_BAND_6G): -#endif /* WL_6G_BAND */ { - if (band == WLC_BAND_2G || band == WLC_BAND_AUTO) { + if (band == WLC_BAND_6G || band == WLC_BAND_AUTO) { + /* scc */ + channel = sta_channel; + acs_band = wl_cfg80211_get_acs_band(sta_band); + } else { channel = APCS_DEFAULT_2G_CH; + acs_band = wl_cfg80211_get_acs_band(WLC_BAND_2G); } break; } +#endif /* WL_6G_BAND */ case (WLC_BAND_2G): { #ifdef WL_6G_BAND if (band == WLC_BAND_6G) { channel = APCS_DEFAULT_6G_CH; + acs_band = wl_cfg80211_get_acs_band(WLC_BAND_6G); } else #endif /* WL_6G_BAND */ if (band == WLC_BAND_5G) { channel = APCS_DEFAULT_5G_CH; + acs_band = wl_cfg80211_get_acs_band(WLC_BAND_5G); } else if (band == WLC_BAND_AUTO) { #ifdef WL_6G_BAND if (cfg->band_6g_supported) { channel = APCS_DEFAULT_6G_CH; + acs_band = wl_cfg80211_get_acs_band(WLC_BAND_6G); } else { channel = APCS_DEFAULT_5G_CH; + acs_band = wl_cfg80211_get_acs_band(WLC_BAND_5G); } #else channel = APCS_DEFAULT_5G_CH; + acs_band = wl_cfg80211_get_acs_band(WLC_BAND_5G); #endif /* WL_6G_BAND */ + } else { + /* scc */ + channel = sta_channel; + acs_band = wl_cfg80211_get_acs_band(sta_band); } break; } default: /* Intentional fall through to use same sta channel for softap */ channel = sta_channel; + acs_band = wl_cfg80211_get_acs_band(sta_band); break; } - WL_DBG(("band = %d, sta_band=%d acs_channel = %d\n", band, sta_band, channel)); - acs_band = wl_cfg80211_get_acs_band(band); goto done2; } @@ -6723,8 +6876,10 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str, cfg->acs_chspec = (chanspec_t)list->element[0]; channel = wf_chspec_ctlchan((chanspec_t)list->element[0]); acs_band = CHSPEC_BAND((chanspec_t)list->element[0]); - WL_DBG(("cfg->acs_chspec = 0x%x, channel =%d, acs_band =0x%x\n", - cfg->acs_chspec, channel, acs_band)); + WL_INFORM_MEM(("chosen acs_chspec = 0x%x, channel =%d, acs_band =0x%x, " + "sta_channel =%d, sta_acs_band = 0x%x\n", + cfg->acs_chspec, channel, acs_band, + sta_channel, wl_cfg80211_get_acs_band(sta_band))); goto done2; } } else { @@ -6808,7 +6963,8 @@ done2: MFREE(cfg->osh, reqbuf, CHANSPEC_BUF_SIZE); } - WL_INFORM_MEM(("ACS: Channel = %d, acs_band = 0x%x\n", channel, acs_band)); + WL_INFORM_MEM(("band = %d, sta_band=%d acs_channel = %d, acs_band = 0x%x\n", + band, sta_band, channel, acs_band)); if (channel && (acs_band != WLC_ACS_BAND_INVALID)) { freq = wl_channel_to_frequency(channel, acs_band); if (!freq) { @@ -9786,6 +9942,125 @@ exit: MFREE(cfg->osh, command, (buf_size + 1)); return ret; } +#ifdef WLADPS_PRIVATE_CMD +static int +wl_android_set_adps_mode(struct net_device *dev, const char* string_num) +{ + int err = 0, adps_mode; + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); +#ifdef DHD_PM_CONTROL_FROM_FILE + if (g_pm_control) { + return -EPERM; + } +#endif /* DHD_PM_CONTROL_FROM_FILE */ + + adps_mode = bcm_atoi(string_num); + WL_ERR(("%s: SET_ADPS %d\n", __FUNCTION__, adps_mode)); + + if (!(adps_mode == 0 || adps_mode == 1)) { + WL_ERR(("wl_android_set_adps_mode: Invalid value %d.\n", adps_mode)); + return -EINVAL; + } + + err = dhd_enable_adps(dhdp, adps_mode); + if (err != BCME_OK) { + WL_ERR(("failed to set adps mode %d, error = %d\n", adps_mode, err)); + return -EIO; + } + return err; +} +static int +wl_android_get_adps_mode( + struct net_device *dev, char *command, int total_len) +{ + int bytes_written, err = 0; + uint len; + char buf[WLC_IOCTL_SMLEN]; + + bcm_iov_buf_t iov_buf; + bcm_iov_buf_t *ptr = NULL; + wl_adps_params_v1_t *data = NULL; + + uint8 *pdata = NULL; + uint8 band, mode = 0; + + bzero(&iov_buf, sizeof(iov_buf)); + + len = OFFSETOF(bcm_iov_buf_t, data) + sizeof(band); + + iov_buf.version = WL_ADPS_IOV_VER; + iov_buf.len = sizeof(band); + iov_buf.id = WL_ADPS_IOV_MODE; + + pdata = (uint8 *)&iov_buf.data; + + for (band = 1; band <= MAX_BANDS; band++) { + pdata[0] = band; + err = wldev_iovar_getbuf(dev, "adps", &iov_buf, len, + buf, WLC_IOCTL_SMLEN, NULL); + if (err != BCME_OK) { + WL_ERR(("wl_android_get_adps_mode fail to get adps band %d(%d).\n", + band, err)); + return -EIO; + } + ptr = (bcm_iov_buf_t *) buf; + data = (wl_adps_params_v1_t *) ptr->data; + mode = data->mode; + if (mode != OFF) { + break; + } + } + + bytes_written = snprintf(command, total_len, "%s %d", + CMD_GET_ADPS, mode); + return bytes_written; +} + +#ifdef WLADPS_ENERGY_GAIN +static int +wl_android_get_gain_adps( + struct net_device *dev, char *command, int total_len) +{ + int bytes_written; + + int ret = 0; + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); + + ret = dhd_event_log_filter_adps_energy_gain(dhdp); + if (ret < 0) { + return ret; + } + + WL_INFORM(("%s ADPS Energy Gain: %d uAh\n", __FUNCTION__, ret)); + + bytes_written = snprintf(command, total_len, "%s %d uAm", + CMD_GET_GAIN_ADPS, ret); + + return bytes_written; +} + +static int +wl_android_reset_gain_adps( + struct net_device *dev, char *command) +{ + int ret = BCME_OK; + + bcm_iov_buf_t iov_buf; + char buf[WLC_IOCTL_SMLEN] = {0, }; + + iov_buf.version = WL_ADPS_IOV_VER; + iov_buf.id = WL_ADPS_IOV_RESET_GAIN; + iov_buf.len = 0; + + if ((ret = wldev_iovar_setbuf(dev, "adps", &iov_buf, sizeof(iov_buf), + buf, sizeof(buf), NULL)) < 0) { + WL_ERR(("%s fail to reset adps gain (%d)\n", __FUNCTION__, ret)); + } + + return ret; +} +#endif /* WLADPS_ENERGY_GAIN */ +#endif /* WLADPS_PRIVATE_CMD */ #ifdef WL_BCNRECV #define BCNRECV_ATTR_HDR_LEN 30 @@ -11433,7 +11708,6 @@ wl_handle_private_cmd(struct net_device *net, char *command, u32 cmd_len) } else if (strnicmp(command, CMD_ASSOC_CLIENTS, strlen(CMD_ASSOC_CLIENTS)) == 0) { bytes_written = wl_android_get_assoclist(net, command, priv_cmd.total_len); } - #ifdef CUSTOMER_HW4_PRIVATE_CMD else if (strnicmp(command, CMD_ROAM_VSIE_ENAB_SET, strlen(CMD_ROAM_VSIE_ENAB_SET)) == 0) { bytes_written = wl_android_set_roam_vsie_enab(net, command, priv_cmd.total_len); @@ -11459,6 +11733,9 @@ wl_handle_private_cmd(struct net_device *net, char *command, u32 cmd_len) else if (strnicmp(command, CMD_OKC_ENABLE, strlen(CMD_OKC_ENABLE)) == 0) { bytes_written = wl_android_okc_enable(net, command); } + else if (strnicmp(command, CMD_SET_5G160, strlen(CMD_SET_5G160)) == 0) { + bytes_written = wl_android_config_5g160(net, command); + } else if (wl_android_legacy_check_command(net, command)) { bytes_written = wl_android_legacy_private_command(net, command, priv_cmd.total_len); } @@ -11997,6 +12274,23 @@ wl_handle_private_cmd(struct net_device *net, char *command, u32 cmd_len) else if (strnicmp(command, CMD_GET_SNR, strlen(CMD_GET_SNR)) == 0) { bytes_written = wl_android_get_snr(net, command, priv_cmd.total_len); } +#ifdef WLADPS_PRIVATE_CMD + else if (strnicmp(command, CMD_SET_ADPS, strlen(CMD_SET_ADPS)) == 0) { + int skip = strlen(CMD_SET_ADPS) + 1; + bytes_written = wl_android_set_adps_mode(net, (const char*)command+skip); + } + else if (strnicmp(command, CMD_GET_ADPS, strlen(CMD_GET_ADPS)) == 0) { + bytes_written = wl_android_get_adps_mode(net, command, priv_cmd.total_len); + } +#ifdef WLADPS_ENERGY_GAIN + else if (strnicmp(command, CMD_GET_GAIN_ADPS, strlen(CMD_GET_GAIN_ADPS)) == 0) { + bytes_written = wl_android_get_gain_adps(net, command, priv_cmd.total_len); + } + else if (strnicmp(command, CMD_RESET_GAIN_ADPS, strlen(CMD_RESET_GAIN_ADPS)) == 0) { + bytes_written = wl_android_reset_gain_adps(net, command); + } +#endif /* WLADPS_ENERGY_GAIN */ +#endif /* WLADPS_PRIVATE_CMD */ #ifdef DHD_PKT_LOGGING else if (strnicmp(command, CMD_PKTLOG_FILTER_ENABLE, strlen(CMD_PKTLOG_FILTER_ENABLE)) == 0) { diff --git a/wl_cfg80211.c b/wl_cfg80211.c index cfac3f3..e97f78b 100644 --- a/wl_cfg80211.c +++ b/wl_cfg80211.c @@ -5995,7 +5995,7 @@ wl_conn_debug_info(struct bcm_cfg80211 *cfg, struct net_device *dev, wlcfg_assoc #endif /* SIMPLE_MAC_PRINT */ /* Limited info */ - WL_INFORM_MEM(("[%s] %s with " MACDBG " ssid_len:%d chan_cnt:%d eidx:%d", + WL_INFORM_MEM(("[%s] %s with " MACDBG " ssid_len:%d chan_cnt:%d eidx:%d\n", dev->name, info->reassoc ? "Reassoc" : "Connecting", MAC2STRDBG((u8*)(&info->bssid)), info->ssid_len, info->chan_cnt, cfg->eidx.min_connect_idx)); @@ -6121,6 +6121,12 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, WL_ERR(("fw assoc sync failed\n")); } +#ifdef DBG_PKT_MON + /* Start pkt monitor here to avoid probe auth and assoc lost */ + if (dev == bcmcfg_to_prmry_ndev(cfg)) { + wl_pkt_mon_start(cfg, dev); + } +#endif /* DBG_PKT_MON */ if (assoc_info.reassoc) { /* Handle roam to same ESS */ if ((err = wl_handle_reassoc(cfg, dev, &assoc_info)) != BCME_OK) { @@ -6166,10 +6172,7 @@ fail: wl_cfg80211_tdls_config(cfg, TDLS_STATE_DISCONNECT, false); #endif /* WLTDLS */ } else { -#ifdef DBG_PKT_MON - /* start packet log in adv to ensure that EAPOL msgs aren't missed */ - wl_pkt_mon_start(cfg, dev); -#endif /* DBG_PKT_MON */ + } mutex_unlock(&cfg->connect_sync); @@ -10291,13 +10294,6 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev wdev->wiphy->max_num_csa_counters = WL_MAX_NUM_CSA_COUNTERS; #endif /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 12, 0) */ - /* Now we can register wiphy with cfg80211 module */ - err = wiphy_register(wdev->wiphy); - if (unlikely(err < 0)) { - WL_ERR(("Couldn not register wiphy device (%d)\n", err)); - wiphy_free(wdev->wiphy); - } - #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) && (LINUX_VERSION_CODE <= \ KERNEL_VERSION(3, 3, 0))) && defined(WL_IFACE_COMB_NUM_CHANNELS) /* Workaround for a cfg80211 bug */ @@ -10306,19 +10302,17 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) && \ defined(SUPPORT_RANDOM_MAC_SCAN) - wdev->wiphy->features |= (NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR | - NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR); - wdev->wiphy->max_sched_scan_plans = 1; /* multiple plans not supported */ + wdev->wiphy->features |= (NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR | + NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR); + wdev->wiphy->max_sched_scan_plans = 1; /* multiple plans not supported */ #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) && defined(SUPPORT_RANDOM_MAC_SCAN) */ #if defined(WL_SAE) || defined(WL_CLIENT_SAE) - wdev->wiphy->features |= NL80211_FEATURE_SAE; + wdev->wiphy->features |= NL80211_FEATURE_SAE; #endif /* WL_SAE || WL_CLIENT_SAE */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)) && defined(BCMSUP_4WAY_HANDSHAKE) - if (FW_SUPPORTED(dhd, idsup)) { - wiphy_ext_feature_set(wdev->wiphy, NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK); - wiphy_ext_feature_set(wdev->wiphy, NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X); - } + wiphy_ext_feature_set(wdev->wiphy, NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK); + wiphy_ext_feature_set(wdev->wiphy, NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X); #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0) && defined(BCMSUP_4WAY_HANDSHAKE) */ #ifdef WL_SCAN_TYPE /* These scan types will be mapped to default scan on non-supported chipset */ @@ -10328,14 +10322,21 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev wiphy_ext_feature_set(wdev->wiphy, NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN); wdev->wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN; #endif /* WL_SCAN_TYPE */ -#ifdef WL_OCE +#if defined(WL_OCE) && defined(WL_CAP_OCE_STA) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) wiphy_ext_feature_set(wdev->wiphy, NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME); wiphy_ext_feature_set(wdev->wiphy, NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP); wiphy_ext_feature_set(wdev->wiphy, NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE); wiphy_ext_feature_set(wdev->wiphy, NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION); #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) */ -#endif /* WL_OCE */ +#endif /* WL_OCE && WL_CAP_OCE_STA */ + + /* Now we can register wiphy with cfg80211 module */ + err = wiphy_register(wdev->wiphy); + if (unlikely(err < 0)) { + WL_ERR(("Couldn not register wiphy device (%d)\n", err)); + wiphy_free(wdev->wiphy); + } return err; } @@ -11056,7 +11057,7 @@ wl_cfg8021_unlink_bss(struct bcm_cfg80211 *cfg, struct net_device *ndev, u8 *bss if (bss) { cfg80211_unlink_bss(wdev->wiphy, bss); CFG80211_PUT_BSS(wdev->wiphy, bss); - WL_INFORM_MEM(("bss unlinked")); + WL_INFORM_MEM(("bss unlinked\n")); } } } @@ -11577,6 +11578,11 @@ wl_handle_assoc_events(struct bcm_cfg80211 *cfg, /* Intentional fall through */ case WLC_E_ASSOC: wl_get_auth_assoc_status(cfg, as.ndev, e, data); +#ifdef AUTH_ASSOC_STATUS_EXT + if ((as.reason == 0) && (as.status != WLC_E_STATUS_SUCCESS)) { + wl_get_auth_assoc_status_ext(cfg, as.ndev, e); + } +#endif /* AUTH_ASSOC_STATUS_EXT */ break; case WLC_E_ASSOC_RESP_IE: if (as.status != WLC_E_STATUS_SUCCESS) { @@ -11839,7 +11845,7 @@ wl_notify_roaming_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, * here only if WLC_E_LINK event is blocked for specific * security type. */ - if (IS_AKM_SUITE_FT(sec)) { + if (IS_AKM_SUITE_FT(sec) || IS_AKM_SUITE_SAE_FT(sec)) { wl_bss_roaming_done(cfg, ndev, e, data); #ifdef BCMDONGLEHOST /* Arm pkt logging timer */ @@ -11997,7 +12003,7 @@ wl_check_pmstatus(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, } #endif /* CUSTOM_EVENT_PM_WAKE */ -#ifdef QOS_MAP_SET +#if defined(QOS_MAP_SET) || defined(WL_CUSTOM_MAPPING_OF_DSCP) /* get user priority table */ uint8 * wl_get_up_table(dhd_pub_t * dhdp, int idx) @@ -12014,7 +12020,7 @@ wl_get_up_table(dhd_pub_t * dhdp, int idx) return NULL; } -#endif /* QOS_MAP_SET */ +#endif /* defined(QOS_MAP_SET) || defined(WL_CUSTOM_MAPPING_OF_DSCP) */ #if defined(DHD_LOSSLESS_ROAMING) || defined(DBG_PKT_MON) /* @@ -12245,13 +12251,15 @@ static s32 wl_update_bss_info(struct bcm_cfg80211 *cfg, struct net_device *ndev, goto update_bss_info_out; } - WL_INFORM_MEM(("Updated the AP %pM detail in cache\n", curbssid)); + WL_INFORM_MEM(("Updated the AP " MACDBG " detail in cache\n", + MAC2STRDBG(curbssid))); ie = ((u8 *)bi) + bi->ie_offset; ie_len = bi->ie_length; beacon_interval = cpu_to_le16(bi->beacon_period); } else { u16 channel; - WL_INFORM_MEM(("Found AP in the cache - BSSID %pM\n", bss->bssid)); + WL_INFORM_MEM(("Found AP in the cache - BSSID " MACDBG "\n", + MAC2STRDBG(bss->bssid))); channel = wf_chspec_ctlchan(wl_chspec_driver_to_host(bi->chanspec)); freq = wl_channel_to_frequency(channel, CHSPEC_BAND(bi->chanspec)); bss->channel = ieee80211_get_channel(wiphy, freq); @@ -13075,8 +13083,9 @@ wl_notify_rx_mgmt_frame(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, } err = wldev_ioctl_get(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN); - if (err < 0) + if ((err < 0) && (err != BCME_NOTASSOCIATED)) { WL_ERR(("WLC_GET_BSSID error %d\n", err)); + } memcpy(da.octet, ioctl_buf, ETHER_ADDR_LEN); if ((ndev->ieee80211_ptr->iftype == NL80211_IFTYPE_STATION) && @@ -16418,12 +16427,7 @@ int wl_cfg80211_hang(struct net_device *dev, u16 reason) { if (dhd->up == TRUE) { #ifdef WL_CFGVENDOR_SEND_HANG_EVENT -#ifdef CUSOMER_HW4 - wl_cfgvendor_send_hang_event(dev, reason, - dhd->hang_info, dhd->hang_info_cnt); -#else wl_cfgvendor_simple_hang_event(dev, reason); -#endif #else CFG80211_DISCONNECTED(dev, reason, NULL, 0, false, GFP_KERNEL); #endif /* WL_CFGVENDOR_SEND_HANG_EVENT */ @@ -18019,6 +18023,13 @@ wl_cfg80211_filter_vndr_ext_id(const vndr_ie_t *vndrie) WL_DBG(("%s:SKIP ADDING FILS HLP EXTN ID\n", __func__)); return true; } +#ifdef WL_CAP_OCE_STA + if (vndrie->oui[0] == FILS_EXTID_MNG_REQ_PARAMS) { + /* Skip adding fils FILS_MAX_CHANNEL_TIME, its already done in FW */ + WL_DBG(("%s:SKIP ADDING FILS MNG REQ PARAMS \n", __func__)); + return true; + } +#endif /* WL_CAP_OCE_STA */ return false; } @@ -18720,7 +18731,7 @@ static int wl_cfg80211_set_pmk(struct wiphy *wiphy, struct net_device *dev, const struct cfg80211_pmk_conf *conf) { int ret = 0; - wsec_pmk_t pmk; + wsec_pmk_t pmk = {0}; struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); struct wl_security *sec; s32 bssidx; @@ -21253,14 +21264,26 @@ wl_cfg80211_handle_set_ssid_complete(struct bcm_cfg80211 *cfg, wl_assoc_status_t const wl_event_msg_t *event, wl_assoc_state_t assoc_state) { if (as->status != WLC_E_STATUS_SUCCESS) { + struct wl_security *sec = wl_read_prof(cfg, as->ndev, WL_PROF_SEC); + if (sec && sec->auth_assoc_res_status) { + WL_INFORM_MEM(("Assoc fail status %d\n", + sec->auth_assoc_res_status)); + } #ifdef SET_SSID_FAIL_CUSTOM_RC - if (as->status == WLC_E_STATUS_TIMEOUT) { + else if (as->status == WLC_E_STATUS_TIMEOUT) { WL_INFORM_MEM(("overriding reason code %d to %d\n", - as->reason, SET_SSID_FAIL_CUSTOM_RC)); + as->reason, SET_SSID_FAIL_CUSTOM_RC)); as->reason = SET_SSID_FAIL_CUSTOM_RC; } #endif /* SET_SSID_FAIL_CUSTOM_RC */ +#ifdef AUTH_ASSOC_STATUS_EXT + else if (sec && as->status == WLC_E_STATUS_NO_NETWORKS) { + WL_INFORM_MEM(("overriding status code %d to %d\n", + sec->auth_assoc_res_status, AUTH_ASSOC_STATUS_NO_NETWORKS)); + sec->auth_assoc_res_status = AUTH_ASSOC_STATUS_NO_NETWORKS; + } +#endif /* AUTH_ASSOC_STATUS_EXT */ /* Report connect failure */ as->link_action = wl_set_link_action(assoc_state, false); @@ -21283,14 +21306,226 @@ wl_cfg80211_handle_set_ssid_complete(struct bcm_cfg80211 *cfg, wl_assoc_status_t } #ifdef WL_TWT +#define BRCM_TWT_VENDOR_EVENT_BUF_LEN 500 +static int +wl_update_twt_setup_evt_info(struct sk_buff *skb, void *event_data) +{ + s32 err = BCME_OK; + const wl_twt_setup_cplt_t *setup_cplt = (wl_twt_setup_cplt_t *)event_data; + const wl_twt_sdesc_t *sdesc = (const wl_twt_sdesc_t *)&setup_cplt[1]; + + err = nla_put_u32(skb, WIFI_TWT_ATTR_SUB_EVENT, WIFI_TWT_EVENT_SETUP); + if (unlikely(err)) { + WL_ERR(("nla_put_u32 WIFI_TWT_ATTR_SUB_EVENT failed\n")); + goto fail; + } + err = nla_put_u8(skb, WIFI_TWT_ATTR_REASON_CODE, setup_cplt->reason_code); + if (unlikely(err)) { + WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_REASON_CODE failed\n")); + goto fail; + } + err = nla_put_s32(skb, WIFI_TWT_ATTR_STATUS, setup_cplt->status); + if (unlikely(err)) { + WL_ERR(("nla_put_s32 WIFI_TWT_ATTR_STATUS failed\n")); + goto fail; + } + err = nla_put_u8(skb, WIFI_TWT_ATTR_SETUP_CMD, sdesc->setup_cmd); + if (unlikely(err)) { + WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_SETUP_CMD failed\n")); + goto fail; + } + err = nla_put_u8(skb, WIFI_TWT_ATTR_FLOW_FLAGS, sdesc->flow_flags); + if (unlikely(err)) { + WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_FLOW_FLAGS failed\n")); + goto fail; + } + err = nla_put_u8(skb, WIFI_TWT_ATTR_FLOW_ID, sdesc->flow_id); + if (unlikely(err)) { + WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_FLOW_ID failed\n")); + goto fail; + } + err = nla_put_u8(skb, WIFI_TWT_ATTR_CHANNEL, sdesc->channel); + if (unlikely(err)) { + WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_CHANNEL failed\n")); + goto fail; + } + err = nla_put_u8(skb, WIFI_TWT_ATTR_NEGOTIATION_TYPE, sdesc->negotiation_type); + if (unlikely(err)) { + WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_NEGOTIATION_TYPE failed\n")); + goto fail; + } + err = nla_put_u32(skb, WIFI_TWT_ATTR_WAKETIME_H, sdesc->wake_time_h); + if (unlikely(err)) { + WL_ERR(("nla_put_u32 WIFI_TWT_ATTR_WAKETIME_H failed\n")); + goto fail; + } + err = nla_put_u32(skb, WIFI_TWT_ATTR_WAKETIME_L, sdesc->wake_time_l); + if (unlikely(err)) { + WL_ERR(("nla_put_u32 WIFI_TWT_ATTR_WAKETIME_L failed\n")); + goto fail; + } + err = nla_put_u32(skb, WIFI_TWT_ATTR_WAKE_DURATION, sdesc->wake_dur); + if (unlikely(err)) { + WL_ERR(("nla_put_u32 WIFI_TWT_ATTR_WAKE_DURATION failed\n")); + goto fail; + } + err = nla_put_u32(skb, WIFI_TWT_ATTR_WAKE_INTERVAL, sdesc->wake_int); + if (unlikely(err)) { + WL_ERR(("nla_put_u32 WIFI_TWT_ATTR_WAKE_INTERVAL failed\n")); + goto fail; + } + +fail: + return err; +} + +static int +wl_update_twt_teardown_evt_info(struct sk_buff *skb, void *event_data) +{ + s32 err = BCME_OK; + const wl_twt_teardown_cplt_t *td_cplt = (wl_twt_teardown_cplt_t *)event_data; + const wl_twt_teardesc_t *teardesc = (const wl_twt_teardesc_t *)&td_cplt[1]; + + err = nla_put_u32(skb, WIFI_TWT_ATTR_SUB_EVENT, WIFI_TWT_EVENT_TEARDOWN); + if (unlikely(err)) { + WL_ERR(("nla_put_u32 WIFI_TWT_ATTR_SUB_EVENT failed\n")); + goto fail; + } + err = nla_put_u8(skb, WIFI_TWT_ATTR_REASON_CODE, td_cplt->reason_code); + if (unlikely(err)) { + WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_REASON_CODE failed\n")); + goto fail; + } + err = nla_put_s32(skb, WIFI_TWT_ATTR_STATUS, td_cplt->status); + if (unlikely(err)) { + WL_ERR(("nla_put_s32 WIFI_TWT_ATTR_STATUS failed\n")); + goto fail; + } + err = nla_put_u8(skb, WIFI_TWT_ATTR_FLOW_ID, teardesc->flow_id); + if (unlikely(err)) { + WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_FLOW_ID failed\n")); + goto fail; + } + err = nla_put_u8(skb, WIFI_TWT_ATTR_NEGOTIATION_TYPE, teardesc->negotiation_type); + if (unlikely(err)) { + WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_NEGOTIATION_TYPE failed\n")); + goto fail; + } + err = nla_put_u8(skb, WIFI_TWT_ATTR_BID, teardesc->bid); + if (unlikely(err)) { + WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_BID failed\n")); + goto fail; + } + err = nla_put_s32(skb, WIFI_TWT_ATTR_ALLTWT, teardesc->alltwt); + if (unlikely(err)) { + WL_ERR(("nla_put_s32 WIFI_TWT_ATTR_ALLTWT failed\n")); + goto fail; + } + +fail: + return err; +} + +static int +wl_update_twt_info_frm_evt_info(struct sk_buff *skb, void *event_data) +{ + s32 err = BCME_OK; + const wl_twt_info_cplt_t *info_cplt = (wl_twt_info_cplt_t *)event_data; + const wl_twt_infodesc_t *infodesc = (const wl_twt_infodesc_t *)&info_cplt[1]; + + err = nla_put_u32(skb, WIFI_TWT_ATTR_SUB_EVENT, WIFI_TWT_EVENT_INFO_FRM); + if (unlikely(err)) { + WL_ERR(("nla_put_u32 WIFI_TWT_ATTR_SUB_EVENT failed\n")); + goto fail; + } + err = nla_put_u8(skb, WIFI_TWT_ATTR_REASON_CODE, info_cplt->reason_code); + if (unlikely(err)) { + WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_REASON_CODE failed\n")); + goto fail; + } + err = nla_put_s32(skb, WIFI_TWT_ATTR_STATUS, info_cplt->status); + if (unlikely(err)) { + WL_ERR(("nla_put_s32 WIFI_TWT_ATTR_STATUS failed\n")); + goto fail; + } + err = nla_put_u8(skb, WIFI_TWT_ATTR_FLOW_FLAGS, infodesc->flow_flags); + if (unlikely(err)) { + WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_FLOW_FLAGS failed\n")); + goto fail; + } + err = nla_put_u8(skb, WIFI_TWT_ATTR_FLOW_ID, infodesc->flow_id); + if (unlikely(err)) { + WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_FLOW_ID failed\n")); + goto fail; + } + err = nla_put_u32(skb, WIFI_TWT_ATTR_NEXT_TWT_H, infodesc->next_twt_h); + if (unlikely(err)) { + WL_ERR(("nla_put_u32 WIFI_TWT_ATTR_NEXT_TWT_H failed\n")); + goto fail; + } + err = nla_put_u32(skb, WIFI_TWT_ATTR_NEXT_TWT_L, infodesc->next_twt_l); + if (unlikely(err)) { + WL_ERR(("nla_put_u32 WIFI_TWT_ATTR_NEXT_TWT_L failed\n")); + goto fail; + } + +fail: + return err; +} + static s32 wl_notify_twt_event(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, const wl_event_msg_t *e, void *data) { - uint32 type; - type = ntoh32(e->event_type); - WL_DBG(("TWT event type %d\n", type)); + struct sk_buff *skb = NULL; + gfp_t kflags; + struct wiphy *wiphy = bcmcfg_to_wiphy(cfg); + int err = BCME_OK; + uint32 event_type; + struct net_device *ndev = bcmcfg_to_prmry_ndev(cfg); + + event_type = ntoh32(e->event_type); + kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; + skb = CFG80211_VENDOR_EVENT_ALLOC(wiphy, ndev_to_wdev(ndev), BRCM_TWT_VENDOR_EVENT_BUF_LEN, + BRCM_VENDOR_EVENT_TWT, kflags); + if (!skb) { + WL_ERR(("skb alloc failed")); + err = BCME_NOMEM; + goto fail; + } + + switch (event_type) { + case WLC_E_TWT_SETUP: + err = wl_update_twt_setup_evt_info(skb, data); + break; + case WLC_E_TWT_TEARDOWN: + err = wl_update_twt_teardown_evt_info(skb, data); + break; + case WLC_E_TWT_INFO_FRM: + err = wl_update_twt_info_frm_evt_info(skb, data); + break; + default: + WL_ERR(("Invalid event type %d", event_type)); + err = BCME_UNSUPPORTED; + break; + } + + if (err) { + goto fail; + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) + cfg80211_vendor_event(skb, kflags); +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */ return BCME_OK; + +fail: + /* Free skb for failure cases */ + if (skb) { + kfree_skb(skb); + } + + return err; } #endif /* WL_TWT */ @@ -21597,3 +21832,61 @@ done: return err; } #endif /* WL_CLIENT_SAE */ + +#ifdef AUTH_ASSOC_STATUS_EXT +s32 +wl_get_auth_assoc_status_ext(struct bcm_cfg80211 *cfg, struct net_device *ndev, + const wl_event_msg_t *e) +{ + u32 event = ntoh32(e->event_type); + s32 status = ntoh32(e->status); + struct wl_security *sec = wl_read_prof(cfg, ndev, WL_PROF_SEC); + u32 reason = 0; + + if (!sec) { + WL_ERR(("sec is NULL\n")); + return 0; + } + switch (event) { + case WLC_E_AUTH: + if (ntoh32(e->auth_type) == DOT11_SAE) { + /* SAE Authentication */ + if (status == WLC_E_STATUS_NO_ACK) { + reason = AUTH_ASSOC_STATUS_SAE_AUTH_NOACK; + } else if (status == WLC_E_STATUS_TIMEOUT) { + reason = AUTH_ASSOC_STATUS_SAE_AUTH_NORESP; + } else { + reason = AUTH_ASSOC_STATUS_SAE_AUTH_FAIL; + } + } else { + /* Open Authentication */ + if (status == WLC_E_STATUS_NO_ACK) { + reason = AUTH_ASSOC_STATUS_OPEN_AUTH_NOACK; + } else if (status == WLC_E_STATUS_TIMEOUT) { + reason = AUTH_ASSOC_STATUS_OPEN_AUTH_NORESP; + } else { + reason = AUTH_ASSOC_STATUS_OPEN_AUTH_FAIL; + } + } + break; + case WLC_E_ASSOC: + if (status == WLC_E_STATUS_NO_ACK) { + reason = AUTH_ASSOC_STATUS_ASSOC_NOACK; + } else if (status == WLC_E_STATUS_TIMEOUT) { + reason = AUTH_ASSOC_STATUS_ASSOC_NORESP; + } else { + reason = AUTH_ASSOC_STATUS_ASSOC_FAIL; + } + break; + default: + break; + } + + if (reason) { + WL_DBG(("event %d status %d reason %d\n", + event, status, reason)); + sec->auth_assoc_res_status = reason; + } + return 0; +} +#endif /* AUTH_ASSOC_STATUS_EXT */ diff --git a/wl_cfg80211.h b/wl_cfg80211.h index 2138b2a..148c946 100644 --- a/wl_cfg80211.h +++ b/wl_cfg80211.h @@ -193,6 +193,7 @@ struct wl_ibss; #endif /* IL_BIGENDIAN */ #define WL_DBG_NONE 0 +#define WL_DBG_PNO (1 << 6) #define WL_DBG_P2P_ACTION (1 << 5) #define WL_DBG_TRACE (1 << 4) #define WL_DBG_SCAN (1 << 3) @@ -434,6 +435,8 @@ do { \ WL_DBG_PRINT_SYSTEM_TIME; \ pr_cont(CFG80211_ERROR_TEXT "%s : ", __func__); \ pr_cont args; \ + DHD_LOG_DUMP_WRITE_TS_FN; \ + DHD_LOG_DUMP_WRITE args; \ } \ } while (0) #define WL_ERR_MEM(args) \ @@ -602,7 +605,15 @@ do { \ #else /* !(WL_DBG_LEVEL > 0) */ #define WL_DBG(args) #endif /* (WL_DBG_LEVEL > 0) */ -#define WL_PNO(x) +#define WL_PNO(args) \ +do { \ + if (wl_dbg_level & WL_DBG_PNO) { \ + WL_DBG_PRINT_SYSTEM_TIME; \ + pr_cont(CFG80211_SCAN_TEXT "%s :", __func__); \ + pr_cont args; \ + } \ +} while (0) + #define WL_SD(x) #define WL_SCAN_RETRY_MAX 3 @@ -1474,9 +1485,8 @@ typedef struct wl_bssid_prune_evt_info wl_bssid_pruned_evt_info_t; #endif /* WL_NAN2P */ #endif /* WL_NAN */ -#ifdef WL_IFACE_MGMT #define WL_IFACE_NOT_PRESENT -1 - +#ifdef WL_IFACE_MGMT typedef enum iface_conc_policy { WL_IF_POLICY_DEFAULT = 0, WL_IF_POLICY_FCFS = 1, @@ -1656,6 +1666,11 @@ typedef struct wl_event_idx { u32 min_connect_idx; } wl_event_idx_t; +typedef struct { + u32 band; + u32 bw_cap; +} wl_bw_cap_t; + /* private data of cfg80211 interface */ struct bcm_cfg80211 { struct wireless_dev *wdev; /* representing cfg cfg80211 device */ @@ -1812,9 +1827,9 @@ struct bcm_cfg80211 { s32 tdls_mgmt_freq; #endif /* WLTDLS */ bool need_wait_afrx; -#ifdef QOS_MAP_SET +#if defined(QOS_MAP_SET) || defined(WL_CUSTOM_MAPPING_OF_DSCP) uint8 *up_table; /* user priority table, size is UP_TABLE_MAX */ -#endif /* QOS_MAP_SET */ +#endif /* QOS_MAP_SET || WL_CUSTOM_MAPPING_OF_DSCP */ struct ether_addr last_roamed_addr; bool rcc_enabled; /* flag for Roam channel cache feature */ u16 ap_oper_channel; @@ -2649,6 +2664,7 @@ wl_iftype_to_str(int wl_iftype) #define IS_AKM_SUITE_FT(sec) ({BCM_REFERENCE(sec); FALSE;}) #endif /* WLFBT */ +#define IS_AKM_SUITE_SAE_FT(sec) (sec->wpa_auth == WLAN_AKM_SUITE_FT_OVER_SAE) #define IS_AKM_SUITE_CCKM(sec) ({BCM_REFERENCE(sec); FALSE;}) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) @@ -2908,9 +2924,9 @@ do { \ } \ } while (0) -#ifdef QOS_MAP_SET +#if defined(QOS_MAP_SET) || defined(WL_CUSTOM_MAPPING_OF_DSCP) extern uint8 *wl_get_up_table(dhd_pub_t * dhdp, int idx); -#endif /* QOS_MAP_SET */ +#endif /* QOS_MAP_SET || WL_CUSTOM_MAPPING_OF_DSCP */ #define P2PO_COOKIE 65535 u64 wl_cfg80211_get_new_roc_id(struct bcm_cfg80211 *cfg); @@ -3053,4 +3069,25 @@ extern s32 wl_handle_auth_event(struct bcm_cfg80211 *cfg, struct net_device *nde #ifdef WL_CFGVENDOR_SEND_ALERT_EVENT extern int wl_cfg80211_alert(struct net_device *dev); #endif /* WL_CFGVENDOR_SEND_ALERT_EVENT */ + +#ifdef AUTH_ASSOC_STATUS_EXT +typedef enum auth_assoc_status_ext { + /* WLC_E_SET_SSID */ + AUTH_ASSOC_STATUS_NO_NETWORKS = 1025, + /* WLC_E_AUTH */ + AUTH_ASSOC_STATUS_OPEN_AUTH_NOACK, + AUTH_ASSOC_STATUS_OPEN_AUTH_NORESP, + AUTH_ASSOC_STATUS_OPEN_AUTH_FAIL, + AUTH_ASSOC_STATUS_SAE_AUTH_NOACK, + AUTH_ASSOC_STATUS_SAE_AUTH_NORESP, + AUTH_ASSOC_STATUS_SAE_AUTH_FAIL, + /* WLC_E_ASSOC */ + AUTH_ASSOC_STATUS_ASSOC_NOACK, + AUTH_ASSOC_STATUS_ASSOC_NORESP, + AUTH_ASSOC_STATUS_ASSOC_FAIL, + AUTH_ASSOC_STATUE_MAX /* MAX Status Code */ +} auth_assoc_status_ext_t; +extern s32 wl_get_auth_assoc_status_ext(struct bcm_cfg80211 *cfg, + struct net_device *ndev, const wl_event_msg_t *e); +#endif /* AUTH_ASSOC_STATUS_EXT */ #endif /* _wl_cfg80211_h_ */ diff --git a/wl_cfgnan.c b/wl_cfgnan.c index 3451fd0..d45d5e1 100644 --- a/wl_cfgnan.c +++ b/wl_cfgnan.c @@ -4294,7 +4294,7 @@ wl_cfgnan_suspend_all_geofence_rng_sessions(struct net_device *ndev, struct bcm_cfg80211 *cfg = wl_get_cfg(ndev); dhd_pub_t *dhd = (struct dhd_pub *)(cfg->pub); - WL_INFORM_MEM(("Suspending all geofence sessions: " + WL_MEM(("Suspending all geofence sessions: " "suspend_reason = %d\n", suspend_reason)); cancel_flags |= NAN_RNG_TERM_FLAG_IMMEDIATE; @@ -4495,8 +4495,7 @@ wl_cfgnan_trigger_geofencing_ranging(struct net_device *dev, exit: if (ret) { - WL_ERR(("wl_cfgnan_trigger_geofencing_ranging: Failed to " - "trigger ranging, peer: " MACDBG " ret" + WL_ERR(("Failed to trigger ranging, peer: " MACDBG " ret" " = (%d), err_at = %d\n", MAC2STRDBG(peer_addr), ret, err_at)); } @@ -7956,21 +7955,21 @@ exit: static void wl_nan_print_status(wl_nan_conf_status_t *nstatus) { - WL_INFORM_MEM(("> NMI: " MACDBG " Cluster_ID: " MACDBG "\n", + WL_DBG(("> NMI: " MACDBG " Cluster_ID: " MACDBG "\n", MAC2STRDBG(nstatus->nmi.octet), MAC2STRDBG(nstatus->cid.octet))); - WL_INFORM_MEM(("> NAN Device Role %s\n", nan_role_to_str(nstatus->role))); - WL_INFORM_MEM(("> Social channels: %d, %d\n", + WL_DBG(("> NAN Device Role %s\n", nan_role_to_str(nstatus->role))); + WL_DBG(("> Social channels: %d, %d\n", nstatus->social_chans[0], nstatus->social_chans[1])); - WL_INFORM_MEM(("> Master_rank: " NMRSTR " AMR : " NMRSTR " Hop Count : %d, AMBTT : %d\n", + WL_DBG(("> Master_rank: " NMRSTR " AMR : " NMRSTR " Hop Count : %d, AMBTT : %d\n", NMR2STR(nstatus->mr), NMR2STR(nstatus->amr), nstatus->hop_count, nstatus->ambtt)); - WL_INFORM_MEM(("> Cluster TSF_H: %x , Cluster TSF_L: %x\n", + WL_DBG(("> Cluster TSF_H: %x , Cluster TSF_L: %x\n", nstatus->cluster_tsf_h, nstatus->cluster_tsf_l)); } @@ -8091,7 +8090,7 @@ wl_cfgnan_reset_geofence_ranging(struct bcm_cfg80211 *cfg, mutex_lock(&rtt_status->rtt_mutex); } - WL_INFORM_MEM(("wl_cfgnan_reset_geofence_ranging: " + WL_MEM(("wl_cfgnan_reset_geofence_ranging: " "sched_reason = %d, cur_idx = %d, target_cnt = %d\n", sched_reason, rtt_status->geofence_cfg.cur_target_idx, rtt_status->geofence_cfg.geofence_target_cnt)); @@ -8110,7 +8109,7 @@ wl_cfgnan_reset_geofence_ranging(struct bcm_cfg80211 *cfg, * Remove all valid ranging inst */ if (rng_inst) { - WL_INFORM_MEM(("Removing Ranging Instance " MACDBG "\n", + WL_MEM(("Removing Ranging Instance " MACDBG "\n", MAC2STRDBG(&(rng_inst->peer_addr)))); bzero(rng_inst, sizeof(*rng_inst)); } @@ -8166,7 +8165,7 @@ wl_cfgnan_reset_geofence_ranging(struct bcm_cfg80211 *cfg, exit: if (reset_req_drop) { - WL_INFORM_MEM(("reset geofence req dropped, reason = %d\n", + WL_MEM(("reset geofence req dropped, reason = %d\n", reset_req_drop)); } if (need_rtt_mutex == TRUE) { @@ -8329,9 +8328,9 @@ wl_cfgnan_notify_nan_status(struct bcm_cfg80211 *cfg, /* get nan status info as-is */ bcm_xtlv_t *xtlv = (bcm_xtlv_t *)event_data; wl_nan_conf_status_t *nstatus = (wl_nan_conf_status_t *)xtlv->data; - WL_INFORM_MEM((">> Nan Mac Event Received: %s (num=%d, len=%d)\n", + WL_DBG((">> Nan Mac Event Received: %s (num=%d, len=%d)\n", nan_event_to_str(event_num), event_num, data_len)); - WL_INFORM_MEM(("Nan Device Role %s\n", nan_role_to_str(nstatus->role))); + WL_DBG(("Nan Device Role %s\n", nan_role_to_str(nstatus->role))); /* Mapping to common struct between DHD and HAL */ nan_event_data->enabled = nstatus->enabled; ret = memcpy_s(&nan_event_data->local_nmi, ETHER_ADDR_LEN, @@ -8615,9 +8614,18 @@ wl_cfgnan_notify_nan_status(struct bcm_cfg80211 *cfg, &rng_inst->peer_addr); if (!wl_cfgnan_geofence_retry_check(rng_inst, range_term->reason_code)) { - /* Report on ranging failure */ - wl_cfgnan_disc_result_on_geofence_cancel(cfg, - rng_inst); + if ((range_term->reason_code != + NAN_RNG_TERM_USER_REQ) && + range_term->reason_code != + NAN_RNG_TERM_PEER_REQ) { + /* + * Report on ranging failure + * Dont report for self or peer + * termination reason codes + */ + wl_cfgnan_disc_result_on_geofence_cancel + (cfg, rng_inst); + } WL_TRACE(("Reset the state on terminate\n")); geofence_target = dhd_rtt_get_geofence_target(dhd, &rng_inst->peer_addr, &index); diff --git a/wl_cfgnan.h b/wl_cfgnan.h index 90bb286..13525a6 100644 --- a/wl_cfgnan.h +++ b/wl_cfgnan.h @@ -816,6 +816,7 @@ bool wl_cfgnan_ranging_is_in_prog_for_peer(struct bcm_cfg80211 *cfg, #endif /* RTT_SUPPORT */ typedef enum { + NAN_ATTRIBUTE_INVALID = 0, NAN_ATTRIBUTE_HEADER = 100, NAN_ATTRIBUTE_HANDLE = 101, NAN_ATTRIBUTE_TRANSAC_ID = 102, @@ -946,7 +947,8 @@ typedef enum { NAN_ATTRIBUTE_DISCOVERY_BEACON_INTERVAL = 224, NAN_ATTRIBUTE_NSS = 225, NAN_ATTRIBUTE_ENABLE_RANGING = 226, - NAN_ATTRIBUTE_DW_EARLY_TERM = 227 + NAN_ATTRIBUTE_DW_EARLY_TERM = 227, + NAN_ATTRIBUTE_MAX = 228 } NAN_ATTRIBUTE; enum geofence_suspend_reason { diff --git a/wl_cfgp2p.c b/wl_cfgp2p.c index df8054e..f09d291 100644 --- a/wl_cfgp2p.c +++ b/wl_cfgp2p.c @@ -1673,8 +1673,8 @@ wl_cfgp2p_action_tx_complete(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev #define ETHER_LOCAL_ADDR 0x02 s32 -wl_actframe_fillup_v2(wl_af_params_v2_t *af_params_v2_p, wl_af_params_t *af_params, - const u8 *sa, uint16 wl_af_params_size) +wl_actframe_fillup_v2(struct net_device *dev, wl_af_params_v2_t *af_params_v2_p, + wl_af_params_t *af_params, const u8 *sa, uint16 wl_af_params_size) { s32 err = 0; wl_action_frame_v2_t *action_frame_v2_p; @@ -1699,8 +1699,9 @@ wl_actframe_fillup_v2(wl_af_params_v2_t *af_params_v2_p, wl_af_params_t *af_para WL_ERR(("actframe :memcpy failed\n")); return -ENOMEM; } - /* check if local admin bit is set */ - if (sa[0] & ETHER_LOCAL_ADDR) { + /* check if local admin bit is set and addr is different from ndev addr */ + if ((sa[0] & ETHER_LOCAL_ADDR) && + memcmp(sa, dev->dev_addr, ETH_ALEN)) { /* Use mask to avoid randomization, as the address from supplicant * is already randomized. */ @@ -1763,7 +1764,7 @@ wl_cfgp2p_tx_action_frame(struct bcm_cfg80211 *cfg, struct net_device *dev, WL_ERR(("unable to allocate frame\n")); return -ENOMEM; } - ret = wl_actframe_fillup_v2(af_params_v2_p, af_params, sa, + ret = wl_actframe_fillup_v2(dev, af_params_v2_p, af_params, sa, wl_af_params_size); if (ret != BCME_OK) { WL_ERR(("unable to fill actframe_params, ret %d\n", ret)); diff --git a/wl_cfgp2p.h b/wl_cfgp2p.h index 83b2997..c7450f3 100644 --- a/wl_cfgp2p.h +++ b/wl_cfgp2p.h @@ -346,8 +346,8 @@ wl_cfgp2p_tx_action_frame(struct bcm_cfg80211 *cfg, struct net_device *dev, wl_af_params_t *af_params, s32 bssidx, const u8 *sa); extern s32 -wl_actframe_fillup_v2(wl_af_params_v2_t *af_params_v2_p, wl_af_params_t *af_params, - const u8 *sa, uint16 wl_af_params_size); +wl_actframe_fillup_v2(struct net_device *dev, wl_af_params_v2_t *af_params_v2_p, + wl_af_params_t *af_params, const u8 *sa, uint16 wl_af_params_size); extern void wl_cfgp2p_generate_bss_mac(struct bcm_cfg80211 *cfg, struct ether_addr *primary_addr); diff --git a/wl_cfgscan.c b/wl_cfgscan.c index 3516952..806778d 100644 --- a/wl_cfgscan.c +++ b/wl_cfgscan.c @@ -3556,7 +3556,7 @@ wl_cfg80211_sched_scan_start(struct wiphy *wiphy, pno_time = PNO_TIME; } - WL_DBG(("Enter. ssids:%d match_sets:%d pno_time:%d pno_repeat:%d channels:%d\n", + WL_INFORM(("Enter. ssids:%d match_sets:%d pno_time:%d pno_repeat:%d channels:%d\n", request->n_ssids, request->n_match_sets, pno_time, pno_repeat, request->n_channels)); @@ -3689,8 +3689,7 @@ wl_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev) struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub); - WL_DBG(("Enter \n")); - WL_PNO((">>> SCHED SCAN STOP\n")); + WL_INFORM((">>> SCHED SCAN STOP\n")); #if defined(BCMDONGLEHOST) if (dhd_dev_pno_stop_for_ssid(dev) < 0) { @@ -5412,10 +5411,10 @@ static int wl_cfgscan_acs_parse_result(acs_selected_channels_t *pResult, return BCME_BADARG; } - chspec_ctl_freq = wl_channel_to_frequency(wf_chspec_ctlchan(ch_chosen), - CHSPEC_BAND(ch_chosen)); - chspec_center_ch = CHSPEC_CHANNEL(ch_chosen); - chspec_band = CHSPEC_BAND(ch_chosen); + chspec_ctl_freq = wl_channel_to_frequency(wf_chspec_ctlchan((chanspec_t)ch_chosen), + CHSPEC_BAND((chanspec_t)ch_chosen)); + chspec_center_ch = wf_chspec_ctlchan((chanspec_t)ch_chosen); + chspec_band = CHSPEC_BAND((chanspec_t)ch_chosen); chspec_bw = CHSPEC_BW(ch_chosen); chspec_sb = CHSPEC_CTL_SB(ch_chosen); WL_TRACE(("%s: ctl_freq=%d, center_ch=%d, band=0x%X, bw=0x%X, sb=0x%X\n", @@ -5813,7 +5812,7 @@ static void wl_cfgscan_acs_result_event(struct work_struct *work) /* construct result */ if (wl_cfgscan_acs_parse_result(&result, ch_chosen, pParameter) < 0) { - WL_ERR(("%s: fail to conver the result\n", __FUNCTION__)); + WL_ERR(("%s: fail to convert the result\n", __FUNCTION__)); ret = BCME_BADARG; break; } @@ -5837,14 +5836,14 @@ static void wl_cfgscan_acs_result_event(struct work_struct *work) } WL_TRACE(("%s: good to get skb=0x%p\n", __FUNCTION__, skb)); - if ((nla_put_u16(skb, BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ, result.pri_freq) < 0) || - (nla_put_u16(skb, BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ, result.sec_freq) < 0) || + if ((nla_put_u32(skb, BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ, result.pri_freq) < 0) || + (nla_put_u32(skb, BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ, result.sec_freq) < 0) || (nla_put_u8(skb, BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL, result.vht_seg0_center_ch) < 0) || (nla_put_u8(skb, BRCM_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL, result.vht_seg1_center_ch) < 0) || (nla_put_u16(skb, BRCM_VENDOR_ATTR_ACS_CHWIDTH, result.ch_width) < 0) || - (nla_put_u32(skb, BRCM_VENDOR_ATTR_ACS_HW_MODE, result.hw_mode) < 0)) { + (nla_put_u8(skb, BRCM_VENDOR_ATTR_ACS_HW_MODE, result.hw_mode) < 0)) { WL_ERR(("%s: Error, fail to fill the result\n", __FUNCTION__)); ret = BCME_BADARG; break; @@ -5899,7 +5898,7 @@ static int wl_cfgscan_acs_do_apcs(struct net_device *dev, int band, chanspec_t * case (WLC_BAND_6G): #endif /* WL_6G_BAND */ if ((band == WLC_BAND_2G) || (band == WLC_BAND_AUTO)) { - chosen = CH20MHZ_CHSPEC(APCS_DEFAULT_2G_CH); + chosen = wl_freq_to_chanspec(APCS_DEFAULT_2G_FREQ); } else { chosen = CH20MHZ_CHSPEC(channel); } @@ -5907,20 +5906,20 @@ static int wl_cfgscan_acs_do_apcs(struct net_device *dev, int band, chanspec_t * case (WLC_BAND_2G): #ifdef WL_6G_BAND if (band & WLC_BAND_6G) { - chosen = CH20MHZ_CHSPEC(APCS_DEFAULT_6G_CH); + chosen = wl_freq_to_chanspec(APCS_DEFAULT_6G_FREQ); } else #endif /* WL_6G_BAND */ if (band & WLC_BAND_5G) { - chosen = CH20MHZ_CHSPEC(APCS_DEFAULT_5G_CH); + chosen = wl_freq_to_chanspec(APCS_DEFAULT_5G_FREQ); } else if (band == WLC_BAND_AUTO) { #ifdef WL_6G_BAND if (cfg->band_6g_supported) { - chosen = CH20MHZ_CHSPEC(APCS_DEFAULT_6G_CH); + chosen = wl_freq_to_chanspec(APCS_DEFAULT_6G_FREQ); } else { - chosen = CH20MHZ_CHSPEC(APCS_DEFAULT_5G_CH); + chosen = wl_freq_to_chanspec(APCS_DEFAULT_5G_FREQ); } #else - chosen = CH20MHZ_CHSPEC(APCS_DEFAULT_5G_CH); + chosen = wl_freq_to_chanspec(APCS_DEFAULT_5G_FREQ); #endif /* WL_6G_BAND */ } else { chosen = CH20MHZ_CHSPEC(channel); diff --git a/wl_cfgscan.h b/wl_cfgscan.h index e5cd213..9a5e2d1 100644 --- a/wl_cfgscan.h +++ b/wl_cfgscan.h @@ -145,6 +145,11 @@ extern int wl_android_get_roam_scan_chanlist(struct bcm_cfg80211 *cfg); extern s32 wl_get_assoc_channels(struct bcm_cfg80211 *cfg, struct net_device *dev, wlcfg_assoc_info_t *info); extern void wl_cfgscan_cancel_scan(struct bcm_cfg80211 *cfg); + +#define APCS_DEFAULT_2G_FREQ 2437u +#define APCS_DEFAULT_5G_FREQ 5745u +#define APCS_DEFAULT_6G_FREQ 5975u + #ifdef DHD_GET_VALID_CHANNELS typedef enum { WIFI_BAND_UNSPECIFIED, diff --git a/wl_cfgvendor.c b/wl_cfgvendor.c index 21cd379..5cb2a59 100644 --- a/wl_cfgvendor.c +++ b/wl_cfgvendor.c @@ -2059,7 +2059,7 @@ wl_cfgvendor_rtt_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, err = -EINVAL; goto exit; } - WL_INFORM_MEM(("Target addr %s, Channel : %s for RTT \n", + WL_MEM(("Target addr %s, Channel : %s for RTT \n", bcm_ether_ntoa((const struct ether_addr *)&rtt_target->addr, eabuf), wf_chspec_ntoa(rtt_target->chanspec, chanbuf))); @@ -3713,7 +3713,7 @@ wl_cfgvendor_nan_parse_dp_sec_info_args(struct wiphy *wiphy, } break; case NAN_ATTRIBUTE_PUBLISH_ID: - cmd_data->pub_id = nla_get_u16(iter); + cmd_data->pub_id = nla_get_u32(iter); break; case NAN_ATTRIBUTE_NDP_ID: cmd_data->ndp_instance_id = nla_get_u32(iter); @@ -4089,11 +4089,11 @@ wl_cfgvendor_nan_parse_discover_args(struct wiphy *wiphy, /* Nan Publish/Subscribe request Attributes */ case NAN_ATTRIBUTE_PUBLISH_ID: - if (nla_len(iter) != sizeof(uint16)) { + if (nla_len(iter) != sizeof(uint32)) { ret = -EINVAL; goto exit; } - cmd_data->pub_id = nla_get_u16(iter); + cmd_data->pub_id = nla_get_u32(iter); cmd_data->local_id = cmd_data->pub_id; break; case NAN_ATTRIBUTE_MAC_ADDR: @@ -5360,7 +5360,7 @@ wl_cfgvendor_nan_dp_ind_event_data_filler(struct sk_buff *msg, nan_event_data_t *event_data) { int ret = BCME_OK; - ret = nla_put_u16(msg, NAN_ATTRIBUTE_PUBLISH_ID, + ret = nla_put_u32(msg, NAN_ATTRIBUTE_PUBLISH_ID, event_data->pub_id); if (unlikely(ret)) { WL_ERR(("Failed to put pub ID, ret=%d\n", ret)); @@ -5458,7 +5458,7 @@ wl_cfgvendor_nan_svc_terminate_event_filler(struct sk_buff *msg, goto fail; } } else { - ret = nla_put_u16(msg, NAN_ATTRIBUTE_PUBLISH_ID, + ret = nla_put_u32(msg, NAN_ATTRIBUTE_PUBLISH_ID, event_data->local_inst_id); if (unlikely(ret)) { WL_ERR(("Failed to put local inst id, ret=%d\n", ret)); @@ -5609,7 +5609,7 @@ wl_cfgvendor_nan_sub_match_event_filler(struct sk_buff *msg, WL_ERR(("Failed to put handle, ret=%d\n", ret)); goto fail; } - ret = nla_put_u16(msg, NAN_ATTRIBUTE_PUBLISH_ID, event_data->pub_id); + ret = nla_put_u32(msg, NAN_ATTRIBUTE_PUBLISH_ID, event_data->pub_id); if (unlikely(ret)) { WL_ERR(("Failed to put pub id, ret=%d\n", ret)); goto fail; @@ -5882,7 +5882,7 @@ wl_cfgvendor_send_nan_event(struct wiphy *wiphy, struct net_device *dev, switch (event_id) { case GOOGLE_NAN_EVENT_DE_EVENT: { - WL_INFORM_MEM(("[NAN] GOOGLE_NAN_DE_EVENT cluster id=" MACDBG "nmi= " MACDBG "\n", + WL_DBG(("[NAN] GOOGLE_NAN_DE_EVENT cluster id=" MACDBG "nmi= " MACDBG "\n", MAC2STRDBG(event_data->clus_id.octet), MAC2STRDBG(event_data->local_nmi.octet))); ret = wl_cfgvendor_nan_de_event_filler(msg, event_data); @@ -7542,6 +7542,12 @@ wl_cfgvendor_dbg_file_dump(struct wiphy *wiphy, buf->data_buf[0], NULL, (uint32)buf->len, DLD_BUF_TYPE_SPECIAL, &pos); break; +#ifdef DHD_SDTC_ETB_DUMP + case DUMP_BUF_ATTR_SDTC_ETB_DUMP: + ret = dhd_sdtc_etb_hal_file_dump(bcmcfg_to_prmry_ndev(cfg), + buf->data_buf[0], (uint32)buf->len); + break; +#endif /* DHD_SDTC_ETB_DUMP */ #ifdef DHD_SSSR_DUMP #ifdef DHD_SSSR_DUMP_BEFORE_SR case DUMP_BUF_ATTR_SSSR_C0_D11_BEFORE : @@ -8339,6 +8345,34 @@ static int wl_cfgvendor_nla_put_pktlogdump_data(struct sk_buff *skb, } #endif /* DHD_PKT_LOGGING */ +#ifdef DHD_SDTC_ETB_DUMP +static int wl_cfgvendor_nla_put_sdtc_etb_dump_data(struct sk_buff *skb, struct net_device *ndev) +{ + char memdump_path[MEMDUMP_PATH_LEN]; + int ret = BCME_OK; + + dhd_get_memdump_filename(ndev, memdump_path, MEMDUMP_PATH_LEN, "sdtc_etb_dump"); + ret = nla_put_string(skb, DUMP_FILENAME_ATTR_SDTC_ETB_DUMP, memdump_path); + if (unlikely(ret)) { + WL_ERR(("Failed to nla put stdc etb dump path, ret=%d\n", ret)); + goto exit; + } + /* should we give exact length sdtc dump FW has reported dump ? */ + ret = nla_put_u32(skb, DUMP_LEN_ATTR_SDTC_ETB_DUMP, DHD_SDTC_ETB_MEMPOOL_SIZE); + if (unlikely(ret)) { + WL_ERR(("Failed to nla put stdc etb length, ret=%d\n", ret)); + goto exit; + } + +exit: + return ret; +} +#else +static int wl_cfgvendor_nla_put_sdtc_etb_dump_data(struct sk_buff *skb, struct net_device *ndev) +{ + return BCME_OK; +} +#endif /* DHD_SDTC_ETB_DUMP */ static int wl_cfgvendor_nla_put_memdump_data(struct sk_buff *skb, struct net_device *ndev, const uint32 fw_len) { @@ -8377,6 +8411,9 @@ static int wl_cfgvendor_nla_put_dump_data(dhd_pub_t *dhd_pub, struct sk_buff *sk ((ret = wl_cfgvendor_nla_put_sssr_dump_data(skb, ndev)) < 0)) { goto done; } + if ((ret = wl_cfgvendor_nla_put_sdtc_etb_dump_data(skb, ndev)) < 0) { + goto done; + } #ifdef DHD_PKT_LOGGING if ((ret = wl_cfgvendor_nla_put_pktlogdump_data(skb, ndev, FALSE)) < 0) { goto done; @@ -8617,12 +8654,12 @@ static int wl_cfgvendor_dbg_get_rx_pkt_fates(struct wiphy *wiphy, #endif /* DBG_PKT_MON */ #ifdef KEEP_ALIVE +/* max size of IP packet for keep alive */ +#define MKEEP_ALIVE_IP_PKT_MAX 256 + static int wl_cfgvendor_start_mkeep_alive(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) { - /* max size of IP packet for keep alive */ - const int MKEEP_ALIVE_IP_PKT_MAX = 256; - int ret = BCME_OK, rem, type; uint8 mkeep_alive_id = 0; uint8 *ip_pkt = NULL; @@ -8742,6 +8779,15 @@ static int wl_cfgvendor_stop_mkeep_alive(struct wiphy *wiphy, struct wireless_de #endif /* KEEP_ALIVE */ #if defined(APF) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) +const struct nla_policy apf_atrribute_policy[APF_ATTRIBUTE_MAX] = { + [APF_ATTRIBUTE_VERSION] = { .type = NLA_U32 }, + [APF_ATTRIBUTE_MAX_LEN] = { .type = NLA_U32 }, + [APF_ATTRIBUTE_PROGRAM] = { .type = NLA_BINARY }, + [APF_ATTRIBUTE_PROGRAM_LEN] = { .type = NLA_U32 }, +}; +#endif /* LINUX_VERSION >= 5.3 */ + static int wl_cfgvendor_apf_get_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) @@ -9355,6 +9401,482 @@ exit: } #endif /* WL_SAR_TX_POWER */ +#ifdef WL_CUSTOM_MAPPING_OF_DSCP +#define UNUSED_PRIO 0xffu +enum andr_user_ac { + BEST_EFFORT = 0, + BACKGROUND = 1, + VIDEO = 2, + VOICE = 3 +}; +const uint8 default_dscp_mapping_table[UP_TABLE_MAX] = +{ + PRIO_8021D_BE, UNUSED_PRIO, UNUSED_PRIO, UNUSED_PRIO, /* 00 ~ 03 */ + UNUSED_PRIO, UNUSED_PRIO, UNUSED_PRIO, UNUSED_PRIO, /* 04 ~ 07 */ + PRIO_8021D_BK, UNUSED_PRIO, PRIO_8021D_BE, UNUSED_PRIO, /* 08 ~ 11 */ + PRIO_8021D_BE, UNUSED_PRIO, PRIO_8021D_BE, UNUSED_PRIO, /* 12 ~ 15 */ + PRIO_8021D_BE, UNUSED_PRIO, PRIO_8021D_EE, UNUSED_PRIO, /* 16 ~ 19 */ + PRIO_8021D_EE, UNUSED_PRIO, PRIO_8021D_EE, UNUSED_PRIO, /* 20 ~ 23 */ + PRIO_8021D_CL, UNUSED_PRIO, PRIO_8021D_CL, UNUSED_PRIO, /* 24 ~ 27 */ + PRIO_8021D_CL, UNUSED_PRIO, PRIO_8021D_CL, UNUSED_PRIO, /* 28 ~ 31 */ + PRIO_8021D_CL, UNUSED_PRIO, PRIO_8021D_CL, UNUSED_PRIO, /* 32 ~ 35 */ + PRIO_8021D_CL, UNUSED_PRIO, PRIO_8021D_CL, UNUSED_PRIO, /* 36 ~ 39 */ + PRIO_8021D_VI, UNUSED_PRIO, UNUSED_PRIO, UNUSED_PRIO, /* 40 ~ 43 */ + PRIO_8021D_VO, UNUSED_PRIO, PRIO_8021D_VO, UNUSED_PRIO, /* 44 ~ 47 */ + PRIO_8021D_NC, UNUSED_PRIO, UNUSED_PRIO, UNUSED_PRIO, /* 48 ~ 51 */ + UNUSED_PRIO, UNUSED_PRIO, UNUSED_PRIO, UNUSED_PRIO, /* 52 ~ 55 */ + PRIO_8021D_NC, UNUSED_PRIO, UNUSED_PRIO, UNUSED_PRIO, /* 56 ~ 59 */ + UNUSED_PRIO, UNUSED_PRIO, UNUSED_PRIO, UNUSED_PRIO /* 60 ~ 63 */ +}; + +static uint8 custom_dscp2priomap[UP_TABLE_MAX]; + +static int +wl_set_dscp_deafult_priority(uint8* table) +{ + int err = BCME_ERROR; + + err = memcpy_s(table, UP_TABLE_MAX, default_dscp_mapping_table, + sizeof(default_dscp_mapping_table)); + if (unlikely(err)) { + WL_ERR(("Fail to set the defalut dscp.\n")); + } + return err; +} + +static int +wl_cfgvendor_custom_mapping_of_dscp(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + struct bcm_cfg80211 *cfg; + int err = BCME_OK, rem, type; + const struct nlattr *iter; + uint32 dscp_start = 0; + uint32 dscp_end = 0; + uint32 access_category = 0; + uint32 priority = 0; + uint32 dscp; + int32 def_dscp_pri; + + cfg = wl_cfg80211_get_bcmcfg(); + if (!cfg || !cfg->wdev) { + err = BCME_NOTUP; + goto exit; + } + if (!cfg->up_table) { + cfg->up_table = (uint8 *) custom_dscp2priomap; + } + + nla_for_each_attr(iter, data, len, rem) { + type = nla_type(iter); + if (type == CUSTOM_SETTING_ATTRIBUTE_DSCP_START) { + dscp_start = nla_get_u32(iter); + WL_INFORM(("got to dscp_stat value [%d]\n", dscp_start)); + if (dscp_start >= UP_TABLE_MAX) { + err = -EINVAL; + goto exit; + } + } else if (type == CUSTOM_SETTING_ATTRIBUTE_DSCP_END) { + dscp_end = nla_get_u32(iter); + WL_INFORM(("got to dscp_end value [%d]\n", dscp_end)); + if (dscp_end >= UP_TABLE_MAX) { + err = -EINVAL; + goto exit; + } + } else if (type == CUSTOM_SETTING_ATTRIBUTE_ACCESS_CATEGORY) { + access_category = nla_get_u32(iter); + WL_INFORM(("got to access_category value [%d]\n", access_category)); + switch (access_category) { + case BEST_EFFORT: + priority = PRIO_8021D_BE; + break; + case BACKGROUND: + priority = PRIO_8021D_BK; + break; + case VIDEO: + priority = PRIO_8021D_VI; + break; + case VOICE: + priority = PRIO_8021D_VO; + break; + default: + err = -EINVAL; + goto exit; + break; + } + } else { + WL_ERR(("Unknown attr type: %d\n", type)); + err = -EINVAL; + goto exit; + } + } + + if (dscp_end < dscp_start) { + WL_ERR(("dscp_end is lower than dscp_start.\n")); + return -EINVAL; + } + + /* Verify to set DSCP of user priority. */ + for (dscp = dscp_start; dscp <= dscp_end; dscp++) { + def_dscp_pri = default_dscp_mapping_table[dscp]; + if ((def_dscp_pri != 0xff) && (def_dscp_pri != priority)) { + err = -EINVAL; + WL_ERR(("Request priority is %d from %d to %d.\n", + priority, dscp_start, dscp_end)); + WL_ERR(("But conflict with defalut priority of DSCP %d and priority %d.\n", + dscp, def_dscp_pri)); + goto exit; + } + } + + /* Set the custom DSCP of user priority. */ + err = memset_s(cfg->up_table + dscp_start, UP_TABLE_MAX - dscp_start, priority, + dscp_end - dscp_start + 1); + if (unlikely(err)) { + WL_ERR(("Fail to set table\n")); + } + +exit: + return err; + +} + +static int +wl_cfgvendor_custom_mapping_of_dscp_reset(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len) +{ + struct bcm_cfg80211 *cfg; + + cfg = wl_cfg80211_get_bcmcfg(); + if (!cfg || !cfg->wdev) { + return BCME_NOTUP; + } + + if (!cfg->up_table) { + WL_INFORM(("Custom table not set yet.\n")); + return BCME_NOTREADY; + } + + return wl_set_dscp_deafult_priority(cfg->up_table); +} +#endif /* WL_CUSTOM_MAPPING_OF_DSCP */ + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) +const struct nla_policy andr_wifi_attr_policy[ANDR_WIFI_ATTRIBUTE_MAX] = { + [ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET] = { .type = NLA_U32 }, + [ANDR_WIFI_ATTRIBUTE_FEATURE_SET] = { .type = NLA_U32 }, + [ANDR_WIFI_ATTRIBUTE_RANDOM_MAC_OUI] = { .type = NLA_NUL_STRING, .len = 3 }, + [ANDR_WIFI_ATTRIBUTE_NODFS_SET] = { .type = NLA_U32 }, + [ANDR_WIFI_ATTRIBUTE_COUNTRY] = { .type = NLA_NUL_STRING, .len = 3 }, + [ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE] = { .type = NLA_U8 }, + [ANDR_WIFI_ATTRIBUTE_TCPACK_SUP_VALUE] = { .type = NLA_U32 }, + [ANDR_WIFI_ATTRIBUTE_LATENCY_MODE] = { .type = NLA_U32 }, + /* Dont see ANDR_WIFI_ATTRIBUTE_RANDOM_MAC being used currently */ + [ANDR_WIFI_ATTRIBUTE_RANDOM_MAC] = { .type = NLA_U32 }, + [ANDR_WIFI_ATTRIBUTE_TX_POWER_SCENARIO] = { .type = NLA_S8 }, + [ANDR_WIFI_ATTRIBUTE_THERMAL_MITIGATION] = { .type = NLA_S8 }, + [ANDR_WIFI_ATTRIBUTE_THERMAL_COMPLETION_WINDOW] = { .type = NLA_U32 }, +}; + +const struct nla_policy dump_buf_policy[DUMP_BUF_ATTR_MAX] = { + [DUMP_BUF_ATTR_MEMDUMP] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SSSR_C0_D11_BEFORE] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SSSR_C0_D11_AFTER] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SSSR_C1_D11_BEFORE] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SSSR_C1_D11_AFTER] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SSSR_C2_D11_BEFORE] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SSSR_C2_D11_AFTER] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SSSR_DIG_BEFORE] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SSSR_DIG_AFTER] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_TIMESTAMP] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_GENERAL_LOG] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_ECNTRS] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SPECIAL_LOG] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_DHD_DUMP] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_EXT_TRAP] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_HEALTH_CHK] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_PRESERVE_LOG] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_COOKIE] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_FLOWRING_DUMP] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_PKTLOG] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_PKTLOG_DEBUG] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_STATUS_LOG] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_AXI_ERROR] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_RTT_LOG] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_SDTC_ETB_DUMP] = { .type = NLA_BINARY }, +}; + +const struct nla_policy andr_dbg_policy[DEBUG_ATTRIBUTE_MAX] = { + [DEBUG_ATTRIBUTE_GET_DRIVER] = { .type = NLA_BINARY }, + [DEBUG_ATTRIBUTE_GET_FW] = { .type = NLA_BINARY }, + [DEBUG_ATTRIBUTE_RING_ID] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_RING_NAME] = { .type = NLA_NUL_STRING }, + [DEBUG_ATTRIBUTE_RING_FLAGS] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_LOG_LEVEL] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_LOG_TIME_INTVAL] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_LOG_MIN_DATA_SIZE] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_FW_DUMP_LEN] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_FW_DUMP_DATA] = { .type = NLA_U64 }, + [DEBUG_ATTRIBUTE_FW_ERR_CODE] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_RING_DATA] = { .type = NLA_BINARY }, + [DEBUG_ATTRIBUTE_RING_STATUS] = { .type = NLA_BINARY }, + [DEBUG_ATTRIBUTE_RING_NUM] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_DRIVER_DUMP_LEN] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_DRIVER_DUMP_DATA] = { .type = NLA_BINARY }, + [DEBUG_ATTRIBUTE_PKT_FATE_NUM] = { .type = NLA_U32 }, + [DEBUG_ATTRIBUTE_PKT_FATE_DATA] = { .type = NLA_U64 }, + [DEBUG_ATTRIBUTE_HANG_REASON] = { .type = NLA_BINARY }, +}; + +const struct nla_policy brcm_drv_attr_policy[BRCM_ATTR_DRIVER_MAX] = { + [BRCM_ATTR_DRIVER_CMD] = { .type = NLA_NUL_STRING }, + [BRCM_ATTR_DRIVER_KEY_PMK] = { .type = NLA_BINARY, .len = WSEC_MAX_PASSPHRASE_LEN }, + [BRCM_ATTR_DRIVER_FEATURE_FLAGS] = { .type = NLA_BINARY, .len = + ((BRCM_WLAN_VENDOR_FEATURES_MAX / 8) + 1) }, + [BRCM_ATTR_DRIVER_RAND_MAC] = { .type = NLA_BINARY, .len = ETHER_ADDR_LEN }, + [BRCM_ATTR_SAE_PWE] = { .type = NLA_U32 }, +}; + +const struct nla_policy rtt_attr_policy[RTT_ATTRIBUTE_MAX] = { + [RTT_ATTRIBUTE_TARGET_CNT] = { .type = NLA_U8 }, + [RTT_ATTRIBUTE_TARGET_INFO] = { .type = NLA_NESTED }, + [RTT_ATTRIBUTE_TARGET_MAC] = { .type = NLA_BINARY, .len = ETHER_ADDR_LEN }, + [RTT_ATTRIBUTE_TARGET_TYPE] = { .type = NLA_U8 }, + [RTT_ATTRIBUTE_TARGET_PEER] = { .type = NLA_U8 }, + [RTT_ATTRIBUTE_TARGET_CHAN] = { .type = NLA_BINARY }, + [RTT_ATTRIBUTE_TARGET_PERIOD] = { .type = NLA_U32 }, + [RTT_ATTRIBUTE_TARGET_NUM_BURST] = { .type = NLA_U32 }, + [RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST] = { .type = NLA_U32 }, + [RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM] = { .type = NLA_U32 }, + [RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR] = { .type = NLA_U32 }, + [RTT_ATTRIBUTE_TARGET_LCI] = { .type = NLA_U8 }, + [RTT_ATTRIBUTE_TARGET_LCR] = { .type = NLA_U8 }, + [RTT_ATTRIBUTE_TARGET_BURST_DURATION] = { .type = NLA_U32 }, + [RTT_ATTRIBUTE_TARGET_PREAMBLE] = { .type = NLA_U8 }, + [RTT_ATTRIBUTE_TARGET_BW] = { .type = NLA_U8 }, + [RTT_ATTRIBUTE_RESULTS_COMPLETE] = { .type = NLA_U32 }, + [RTT_ATTRIBUTE_RESULTS_PER_TARGET] = { .type = NLA_NESTED }, + [RTT_ATTRIBUTE_RESULT_CNT] = { .type = NLA_U32 }, + [RTT_ATTRIBUTE_RESULT] = { .type = NLA_BINARY, .len = sizeof(rtt_result_t) }, + [RTT_ATTRIBUTE_RESULT_DETAIL] = { .type = NLA_BINARY, + .len = sizeof(struct rtt_result_detail) }, +}; + +#ifdef RSSI_MONITOR_SUPPORT +const struct nla_policy rssi_monitor_attr_policy[RSSI_MONITOR_ATTRIBUTE_MAX] = { + [RSSI_MONITOR_ATTRIBUTE_MAX_RSSI] = { .type = NLA_U32 }, + [RSSI_MONITOR_ATTRIBUTE_MIN_RSSI] = { .type = NLA_U32 }, + [RSSI_MONITOR_ATTRIBUTE_START] = { .type = NLA_U32 } +}; +#endif /* RSSI_MONITOR_SUPPORT */ + +#ifdef KEEP_ALIVE +const struct nla_policy mkeep_alive_attr_policy[MKEEP_ALIVE_ATTRIBUTE_MAX] = { + [MKEEP_ALIVE_ATTRIBUTE_ID] = { .type = NLA_U8 }, + [MKEEP_ALIVE_ATTRIBUTE_IP_PKT] = { .type = NLA_BINARY, .len = MKEEP_ALIVE_IP_PKT_MAX }, + [MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN] = { .type = NLA_U16 }, + [MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR] = { .type = NLA_BINARY, .len = ETHER_ADDR_LEN }, + [MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR] = { .type = NLA_BINARY, .len = ETHER_ADDR_LEN }, + [MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC] = { .type = NLA_U32 }, + [MKEEP_ALIVE_ATTRIBUTE_ETHER_TYPE] = { .type = NLA_U16 } +}; +#endif /* KEEP_ALIVE */ +#ifdef WL_NAN +const struct nla_policy nan_attr_policy[NAN_ATTRIBUTE_MAX] = { + [NAN_ATTRIBUTE_2G_SUPPORT] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_5G_SUPPORT] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_CLUSTER_LOW] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_CLUSTER_HIGH] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_SID_BEACON] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SUB_SID_BEACON] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SYNC_DISC_2G_BEACON] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SYNC_DISC_5G_BEACON] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SDF_2G_SUPPORT] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SDF_5G_SUPPORT] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_HOP_COUNT_LIMIT] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RANDOM_TIME] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_MASTER_PREF] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_OUI] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_WARMUP_TIME] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_CHANNEL] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_24G_CHANNEL] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_5G_CHANNEL] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_CONF_CLUSTER_VAL] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_DWELL_TIME] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SCAN_PERIOD] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_DWELL_TIME_5G] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SCAN_PERIOD_5G] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_AVAIL_BIT_MAP] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_ENTRY_CONTROL] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RSSI_CLOSE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RSSI_MIDDLE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RSSI_PROXIMITY] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RSSI_CLOSE_5G] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RSSI_MIDDLE_5G] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RSSI_PROXIMITY_5G] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RSSI_WINDOW_SIZE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_CIPHER_SUITE_TYPE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SCID_LEN] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_SCID] = { .type = NLA_BINARY, .len = MAX_SCID_LEN }, + [NAN_ATTRIBUTE_2G_AWAKE_DW] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_5G_AWAKE_DW] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_DISC_IND_CFG] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_MAC_ADDR] = { .type = NLA_BINARY, .len = ETHER_ADDR_LEN }, + [NAN_ATTRIBUTE_RANDOMIZATION_INTERVAL] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_CMD_USE_NDPE] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_ENABLE_MERGE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_DISCOVERY_BEACON_INTERVAL] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_NSS] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_ENABLE_RANGING] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_DW_EARLY_TERM] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_TRANSAC_ID] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_PUBLISH_ID] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO] = { .type = NLA_BINARY, .len = + NAN_MAX_SERVICE_SPECIFIC_INFO_LEN }, + [NAN_ATTRIBUTE_SUBSCRIBE_ID] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_SUBSCRIBE_TYPE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_PUBLISH_COUNT] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_PUBLISH_TYPE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_PERIOD] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_TTL] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_SERVICE_NAME_LEN] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_SERVICE_NAME] = { .type = NLA_BINARY, .len = WL_NAN_SVC_HASH_LEN }, + [NAN_ATTRIBUTE_PEER_ID] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_INST_ID] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_SUBSCRIBE_COUNT] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SSIREQUIREDFORMATCHINDICATION] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SUBSCRIBE_MATCH] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_PUBLISH_MATCH] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SERVICERESPONSEFILTER] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SERVICERESPONSEINCLUDE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_USESERVICERESPONSEFILTER] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RX_MATCH_FILTER_LEN] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_RX_MATCH_FILTER] = { .type = NLA_BINARY, .len = MAX_MATCH_FILTER_LEN }, + [NAN_ATTRIBUTE_TX_MATCH_FILTER_LEN] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_TX_MATCH_FILTER] = { .type = NLA_BINARY, .len = MAX_MATCH_FILTER_LEN }, + [NAN_ATTRIBUTE_MAC_ADDR_LIST_NUM_ENTRIES] = { .type = NLA_U16, .len = sizeof(uint16) }, + [NAN_ATTRIBUTE_MAC_ADDR_LIST] = { .type = NLA_BINARY, .len = + (NAN_SRF_MAX_MAC*ETHER_ADDR_LEN) }, + [NAN_ATTRIBUTE_TX_TYPE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SDE_CONTROL_CONFIG_DP] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SDE_CONTROL_RANGE_SUPPORT] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SDE_CONTROL_DP_TYPE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SDE_CONTROL_SECURITY] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RECV_IND_CFG] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_KEY_TYPE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_KEY_LEN] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_KEY_DATA] = { .type = NLA_BINARY, .len = NAN_MAX_PMK_LEN }, + [NAN_ATTRIBUTE_RSSI_THRESHOLD_FLAG] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO_LEN] = { .type = NLA_U16, .len = + sizeof(uint16) }, + [NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO] = { .type = NLA_BINARY, .len = + MAX_SDEA_SVC_INFO_LEN }, + [NAN_ATTRIBUTE_SECURITY] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RANGING_INTERVAL] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_RANGING_INGRESS_LIMIT] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_RANGING_EGRESS_LIMIT] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_RANGING_INDICATION] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_SVC_RESPONDER_POLICY] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_NDP_ID] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_IFACE] = { .type = NLA_BINARY, .len = IFNAMSIZ+1 }, + [NAN_ATTRIBUTE_QOS] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_RSP_CODE] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_INST_COUNT] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_PEER_DISC_MAC_ADDR] = { .type = NLA_BINARY, .len = ETHER_ADDR_LEN }, + [NAN_ATTRIBUTE_PEER_NDI_MAC_ADDR] = { .type = NLA_BINARY, .len = ETHER_ADDR_LEN }, + [NAN_ATTRIBUTE_IF_ADDR] = { .type = NLA_BINARY, .len = ETHER_ADDR_LEN }, + [NAN_ATTRIBUTE_ENTRY_CONTROL] = { .type = NLA_U8, .len = sizeof(uint8) }, + [NAN_ATTRIBUTE_AVAIL_BIT_MAP] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_CHANNEL] = { .type = NLA_U32, .len = sizeof(uint32) }, + [NAN_ATTRIBUTE_NO_CONFIG_AVAIL] = { .type = NLA_U8, .len = sizeof(uint8) }, +}; +#endif /* WL_NAN */ + +const struct nla_policy gscan_attr_policy[GSCAN_ATTRIBUTE_MAX] = { + [GSCAN_ATTRIBUTE_BAND] = { .type = NLA_U32 }, + [GSCAN_ATTRIBUTE_NUM_CHANNELS] = { .type = NLA_U32 }, + [GSCAN_ATTRIBUTE_CHANNEL_LIST] = { .type = NLA_BINARY }, + [GSCAN_ATTRIBUTE_WHITELIST_SSID] = { .type = NLA_BINARY, .len = IEEE80211_MAX_SSID_LEN }, + [GSCAN_ATTRIBUTE_NUM_WL_SSID] = { .type = NLA_U32 }, + [GSCAN_ATTRIBUTE_WL_SSID_LEN] = { .type = NLA_U32 }, + [GSCAN_ATTRIBUTE_WL_SSID_FLUSH] = { .type = NLA_U32 }, + [GSCAN_ATTRIBUTE_WHITELIST_SSID_ELEM] = { .type = NLA_NESTED }, + /* length is sizeof(wl_ssid_whitelist_t) * MAX_SSID_WHITELIST_NUM */ + [GSCAN_ATTRIBUTE_NUM_BSSID] = { .type = NLA_U32 }, + [GSCAN_ATTRIBUTE_BSSID_PREF_LIST] = { .type = NLA_NESTED }, + /* length is sizeof(wl_bssid_pref_list_t) * MAX_BSSID_PREF_LIST_NUM */ + [GSCAN_ATTRIBUTE_BSSID_PREF_FLUSH] = { .type = NLA_U32 }, + [GSCAN_ATTRIBUTE_BSSID_PREF] = { .type = NLA_BINARY, .len = ETH_ALEN }, + [GSCAN_ATTRIBUTE_RSSI_MODIFIER] = { .type = NLA_U32 }, + [GSCAN_ATTRIBUTE_BSSID_BLACKLIST_FLUSH] = { .type = NLA_U32 }, + [GSCAN_ATTRIBUTE_BLACKLIST_BSSID] = { .type = NLA_BINARY, .len = ETH_ALEN }, + [GSCAN_ATTRIBUTE_ROAM_STATE_SET] = { .type = NLA_U32 }, +}; + +const struct nla_policy wake_stat_attr_policy[WAKE_STAT_ATTRIBUTE_MAX] = { + [WAKE_STAT_ATTRIBUTE_TOTAL_CMD_EVENT] = { .type = NLA_U32 }, +#ifdef CUSTOM_WAKE_REASON_STATS + [WAKE_STAT_ATTRIBUTE_CMD_EVENT_WAKE] = { .type = NLA_BINARY, + .len = (MAX_WAKE_REASON_STATS * sizeof(int))}, +#else + [WAKE_STAT_ATTRIBUTE_CMD_EVENT_WAKE] = { .type = NLA_BINARY, + .len = (WLC_E_LAST * sizeof(uint))}, +#endif /* CUSTOM_WAKE_REASON_STATS */ + [WAKE_STAT_ATTRIBUTE_CMD_EVENT_COUNT] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_CMD_EVENT_COUNT_USED] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_TOTAL_DRIVER_FW] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_DRIVER_FW_WAKE] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_DRIVER_FW_COUNT] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_DRIVER_FW_COUNT_USED] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_TOTAL_RX_DATA_WAKE] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_RX_UNICAST_COUNT] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_RX_MULTICAST_COUNT] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_RX_BROADCAST_COUNT] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_RX_ICMP_PKT] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_RX_ICMP6_PKT] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_RX_ICMP6_RA] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_RX_ICMP6_NA] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_RX_ICMP6_NS] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_IPV4_RX_MULTICAST_ADD_CNT] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_IPV6_RX_MULTICAST_ADD_CNT] = { .type = NLA_U32 }, + [WAKE_STAT_ATTRIBUTE_OTHER_RX_MULTICAST_ADD_CNT] = { .type = NLA_U32 }, +}; + +#ifdef WL_SOFTAP_ACS +const struct nla_policy acs_attr_policy[BRCM_VENDOR_ATTR_ACS_LAST] = { + [BRCM_VENDOR_ATTR_ACS_CHANNEL_INVALID] = { .type = NLA_U8 }, + [BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ] = { .type = NLA_U32 }, + [BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ] = { .type = NLA_U32 }, + [BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL] = { .type = NLA_U8 }, + [BRCM_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL] = { .type = NLA_U8 }, + [BRCM_VENDOR_ATTR_ACS_HW_MODE] = { .type = NLA_U8 }, + [BRCM_VENDOR_ATTR_ACS_HT_ENABLED] = { .type = NLA_U8 }, + [BRCM_VENDOR_ATTR_ACS_HT40_ENABLED] = { .type = NLA_U8 }, + [BRCM_VENDOR_ATTR_ACS_VHT_ENABLED] = { .type = NLA_U8 }, + [BRCM_VENDOR_ATTR_ACS_CHWIDTH] = { .type = NLA_U16 }, + [BRCM_VENDOR_ATTR_ACS_CH_LIST] = { .type = NLA_BINARY }, + [BRCM_VENDOR_ATTR_ACS_FREQ_LIST] = { .type = NLA_BINARY }, +}; +#endif /* WL_SOFTAP_ACS */ + +const struct nla_policy hal_start_attr_policy[SET_HAL_START_ATTRIBUTE_MAX] = { + [0] = { .strict_start_type = 0 }, + [SET_HAL_START_ATTRIBUTE_DEINIT] = { .type = NLA_UNSPEC }, + [SET_HAL_START_ATTRIBUTE_PRE_INIT] = { .type = NLA_NUL_STRING }, + [SET_HAL_START_ATTRIBUTE_EVENT_SOCK_PID] = { .type = NLA_U32 }, +}; + +#ifdef WL_CUSTOM_MAPPING_OF_DSCP +const struct nla_policy custom_setting_attr_policy[CUSTOM_SETTING_ATTRIBUTE_MAX] = { + [CUSTOM_SETTING_ATTRIBUTE_DSCP_START] = { .type = NLA_U32 }, + [CUSTOM_SETTING_ATTRIBUTE_DSCP_END] = { .type = NLA_U32 }, + [CUSTOM_SETTING_ATTRIBUTE_ACCESS_CATEGORY] = { .type = NLA_U32 }, +}; +#endif /* WL_CUSTOM_MAPPING_OF_DSCP */ + +#endif /* LINUX_VERSION >= 5.3 */ + static struct wiphy_vendor_command wl_vendor_cmds [] = { { { @@ -9362,7 +9884,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = BRCM_VENDOR_SCMD_PRIV_STR }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_priv_string_handler + .doit = wl_cfgvendor_priv_string_handler, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = brcm_drv_attr_policy, + .maxattr = BRCM_ATTR_DRIVER_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #ifdef BCM_PRIV_CMD_SUPPORT { @@ -9371,7 +9897,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = BRCM_VENDOR_SCMD_BCM_STR }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_priv_bcm_handler + .doit = wl_cfgvendor_priv_bcm_handler, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = brcm_drv_attr_policy, + .maxattr = BRCM_ATTR_DRIVER_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* BCM_PRIV_CMD_SUPPORT */ #if defined(WL_SAE) || defined(WL_CLIENT_SAE) @@ -9390,7 +9920,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = BRCM_VENDOR_SCMD_SET_CONNECT_PARAMS }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_connect_params_handler + .doit = wl_cfgvendor_connect_params_handler, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = brcm_drv_attr_policy, + .maxattr = BRCM_ATTR_DRIVER_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9398,7 +9932,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = BRCM_VENDOR_SCMD_SET_START_AP_PARAMS }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_start_ap_params_handler + .doit = wl_cfgvendor_start_ap_params_handler, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = brcm_drv_attr_policy, + .maxattr = BRCM_ATTR_DRIVER_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #ifdef GSCAN_SUPPORT { @@ -9465,7 +10003,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = GSCAN_SUBCMD_GET_CHANNEL_LIST }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_gscan_get_channel_list + .doit = wl_cfgvendor_gscan_get_channel_list, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = gscan_attr_policy, + .maxattr = GSCAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* GSCAN_SUPPORT || DHD_GET_VALID_CHANNELS */ #ifdef RTT_SUPPORT @@ -9475,7 +10017,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = RTT_SUBCMD_SET_CONFIG }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_rtt_set_config + .doit = wl_cfgvendor_rtt_set_config, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = rtt_attr_policy, + .maxattr = RTT_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9483,7 +10029,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = RTT_SUBCMD_CANCEL_CONFIG }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_rtt_cancel_config + .doit = wl_cfgvendor_rtt_cancel_config, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = rtt_attr_policy, + .maxattr = RTT_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9491,7 +10041,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = RTT_SUBCMD_GETCAPABILITY }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_rtt_get_capability + .doit = wl_cfgvendor_rtt_get_capability, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = rtt_attr_policy, + .maxattr = RTT_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9499,7 +10053,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = RTT_SUBCMD_GETAVAILCHANNEL }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_rtt_get_responder_info + .doit = wl_cfgvendor_rtt_get_responder_info, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = rtt_attr_policy, + .maxattr = RTT_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9507,7 +10065,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = RTT_SUBCMD_SET_RESPONDER }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_rtt_set_responder + .doit = wl_cfgvendor_rtt_set_responder, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = rtt_attr_policy, + .maxattr = RTT_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9515,7 +10077,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = RTT_SUBCMD_CANCEL_RESPONDER }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_rtt_cancel_responder + .doit = wl_cfgvendor_rtt_cancel_responder, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = rtt_attr_policy, + .maxattr = RTT_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* RTT_SUPPORT */ { @@ -9524,7 +10090,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = ANDR_WIFI_SUBCMD_GET_FEATURE_SET }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_get_feature_set + .doit = wl_cfgvendor_get_feature_set, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_wifi_attr_policy, + .maxattr = ANDR_WIFI_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9532,7 +10102,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = ANDR_WIFI_SUBCMD_GET_FEATURE_SET_MATRIX }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_get_feature_set_matrix + .doit = wl_cfgvendor_get_feature_set_matrix, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_wifi_attr_policy, + .maxattr = ANDR_WIFI_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9540,7 +10114,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = ANDR_WIFI_RANDOM_MAC_OUI }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_rand_mac_oui + .doit = wl_cfgvendor_set_rand_mac_oui, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_wifi_attr_policy, + .maxattr = ANDR_WIFI_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #ifdef CUSTOM_FORCE_NODFS_FLAG { @@ -9549,7 +10127,12 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = ANDR_WIFI_NODFS_CHANNELS }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_nodfs_flag + .doit = wl_cfgvendor_set_nodfs_flag, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_wifi_attr_policy, + .maxattr = ANDR_WIFI_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ + }, #endif /* CUSTOM_FORCE_NODFS_FLAG */ { @@ -9558,7 +10141,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = ANDR_WIFI_SET_COUNTRY }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_country + .doit = wl_cfgvendor_set_country, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_wifi_attr_policy, + .maxattr = ANDR_WIFI_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #ifdef LINKSTAT_SUPPORT { @@ -9616,7 +10203,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_SUBCMD_SET_SSID_WHITELIST }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_ssid_whitelist + .doit = wl_cfgvendor_set_ssid_whitelist, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = gscan_attr_policy, + .maxattr = GSCAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { @@ -9625,7 +10216,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_SUBCMD_SET_BSSID_BLACKLIST }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_bssid_blacklist + .doit = wl_cfgvendor_set_bssid_blacklist, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = gscan_attr_policy, + .maxattr = GSCAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* GSCAN_SUPPORT || ROAMEXP_SUPPORT */ #ifdef ROAMEXP_SUPPORT @@ -9635,7 +10230,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_SUBCMD_FW_ROAM_POLICY }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_fw_roaming_state + .doit = wl_cfgvendor_set_fw_roaming_state, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = gscan_attr_policy, + .maxattr = GSCAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9652,7 +10251,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_GET_VER }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_dbg_get_version + .doit = wl_cfgvendor_dbg_get_version, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_dbg_policy, + .maxattr = DEBUG_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #ifdef DHD_LOG_DUMP { @@ -9661,7 +10264,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_GET_FILE_DUMP_BUF }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_dbg_file_dump + .doit = wl_cfgvendor_dbg_file_dump, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = dump_buf_policy, + .maxattr = DUMP_BUF_ATTR_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* DHD_LOG_DUMP */ @@ -9680,7 +10287,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_GET_MEM_DUMP }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_dbg_get_mem_dump + .doit = wl_cfgvendor_dbg_get_mem_dump, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_dbg_policy, + .maxattr = DEBUG_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9688,7 +10299,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_START_LOGGING }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_dbg_start_logging + .doit = wl_cfgvendor_dbg_start_logging, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_dbg_policy, + .maxattr = DEBUG_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9704,7 +10319,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_GET_RING_STATUS }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_dbg_get_ring_status + .doit = wl_cfgvendor_dbg_get_ring_status, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_dbg_policy, + .maxattr = DEBUG_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9712,7 +10331,12 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_GET_RING_DATA }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_dbg_get_ring_data + .doit = wl_cfgvendor_dbg_get_ring_data, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_dbg_policy, + .maxattr = DEBUG_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ + }, #endif /* DEBUGABILITY */ { @@ -9738,7 +10362,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_GET_TX_PKT_FATES }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_dbg_get_tx_pkt_fates + .doit = wl_cfgvendor_dbg_get_tx_pkt_fates, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_dbg_policy, + .maxattr = DEBUG_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9746,7 +10374,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_GET_RX_PKT_FATES }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_dbg_get_rx_pkt_fates + .doit = wl_cfgvendor_dbg_get_rx_pkt_fates, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_dbg_policy, + .maxattr = DEBUG_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* DBG_PKT_MON */ #ifdef KEEP_ALIVE @@ -9756,7 +10388,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_OFFLOAD_SUBCMD_START_MKEEP_ALIVE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_start_mkeep_alive + .doit = wl_cfgvendor_start_mkeep_alive, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = mkeep_alive_attr_policy, + .maxattr = MKEEP_ALIVE_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9764,7 +10400,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_OFFLOAD_SUBCMD_STOP_MKEEP_ALIVE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_stop_mkeep_alive + .doit = wl_cfgvendor_stop_mkeep_alive, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = mkeep_alive_attr_policy, + .maxattr = MKEEP_ALIVE_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* KEEP_ALIVE */ #ifdef WL_NAN @@ -9774,7 +10414,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_ENABLE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_start_handler + .doit = wl_cfgvendor_nan_start_handler, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9782,7 +10426,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_DISABLE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_stop_handler + .doit = wl_cfgvendor_nan_stop_handler, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9790,7 +10438,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_CONFIG }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_config_handler + .doit = wl_cfgvendor_nan_config_handler, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9798,7 +10450,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_REQUEST_PUBLISH }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_req_publish + .doit = wl_cfgvendor_nan_req_publish, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9806,7 +10462,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_REQUEST_SUBSCRIBE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_req_subscribe + .doit = wl_cfgvendor_nan_req_subscribe, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9814,7 +10474,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_CANCEL_PUBLISH }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_cancel_publish + .doit = wl_cfgvendor_nan_cancel_publish, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9822,7 +10486,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_CANCEL_SUBSCRIBE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_cancel_subscribe + .doit = wl_cfgvendor_nan_cancel_subscribe, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9830,7 +10498,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_TRANSMIT }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_transmit + .doit = wl_cfgvendor_nan_transmit, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9847,7 +10519,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_DATA_PATH_IFACE_CREATE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_data_path_iface_create + .doit = wl_cfgvendor_nan_data_path_iface_create, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9855,7 +10531,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_DATA_PATH_IFACE_DELETE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_data_path_iface_delete + .doit = wl_cfgvendor_nan_data_path_iface_delete, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9863,7 +10543,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_DATA_PATH_REQUEST }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_data_path_request + .doit = wl_cfgvendor_nan_data_path_request, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9871,7 +10555,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_DATA_PATH_RESPONSE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_data_path_response + .doit = wl_cfgvendor_nan_data_path_response, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9879,7 +10567,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_DATA_PATH_END }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_data_path_end + .doit = wl_cfgvendor_nan_data_path_end, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #ifdef WL_NAN_DISC_CACHE { @@ -9888,7 +10580,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_DATA_PATH_SEC_INFO }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_data_path_sec_info + .doit = wl_cfgvendor_nan_data_path_sec_info, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* WL_NAN_DISC_CACHE */ { @@ -9905,7 +10601,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = NAN_WIFI_SUBCMD_ENABLE_MERGE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_nan_enable_merge + .doit = wl_cfgvendor_nan_enable_merge, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = nan_attr_policy, + .maxattr = NAN_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* WL_NAN */ #if defined(APF) @@ -9915,16 +10615,23 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = APF_SUBCMD_GET_CAPABILITIES }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_apf_get_capabilities + .doit = wl_cfgvendor_apf_get_capabilities, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = apf_atrribute_policy, + .maxattr = APF_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, - { { .vendor_id = OUI_GOOGLE, .subcmd = APF_SUBCMD_SET_FILTER }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_apf_set_filter + .doit = wl_cfgvendor_apf_set_filter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = apf_atrribute_policy, + .maxattr = APF_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -9932,7 +10639,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = APF_SUBCMD_READ_FILTER_DATA }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_apf_read_filter_data + .doit = wl_cfgvendor_apf_read_filter_data, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = apf_atrribute_policy, + .maxattr = APF_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* APF */ #ifdef NDO_CONFIG_SUPPORT @@ -9942,7 +10653,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_SUBCMD_CONFIG_ND_OFFLOAD }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_configure_nd_offload + .doit = wl_cfgvendor_configure_nd_offload, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_wifi_attr_policy, + .maxattr = ANDR_WIFI_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* NDO_CONFIG_SUPPORT */ #ifdef RSSI_MONITOR_SUPPORT @@ -9952,7 +10667,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_SUBCMD_SET_RSSI_MONITOR }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_rssi_monitor + .doit = wl_cfgvendor_set_rssi_monitor, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = rssi_monitor_attr_policy, + .maxattr = RSSI_MONITOR_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* RSSI_MONITOR_SUPPORT */ #ifdef DHD_WAKE_STATUS @@ -9962,7 +10681,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_GET_WAKE_REASON_STATS }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_get_wake_reason_stats + .doit = wl_cfgvendor_get_wake_reason_stats, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = wake_stat_attr_policy, + .maxattr = WAKE_STAT_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* DHD_WAKE_STATUS */ #ifdef DHDTCPACK_SUPPRESS @@ -9972,7 +10695,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_SUBCMD_CONFIG_TCPACK_SUP }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_tcpack_sup_mode + .doit = wl_cfgvendor_set_tcpack_sup_mode, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_wifi_attr_policy, + .maxattr = ANDR_WIFI_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* DHDTCPACK_SUPPRESS */ #if !defined(BCMSUP_4WAY_HANDSHAKE) || (LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0)) @@ -9982,7 +10709,12 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = BRCM_VENDOR_SCMD_SET_PMK }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_pmk + .doit = wl_cfgvendor_set_pmk, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = brcm_drv_attr_policy, + .maxattr = BRCM_ATTR_DRIVER_MAX +#endif /* LINUX_VERSION >= 5.3 */ + }, #endif /* !BCMSUP_4WAY_HANDSHAKE || LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) */ { @@ -9991,7 +10723,12 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = BRCM_VENDOR_SCMD_GET_FEATURES }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_get_driver_feature + .doit = wl_cfgvendor_get_driver_feature, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = brcm_drv_attr_policy, + .maxattr = BRCM_ATTR_DRIVER_MAX +#endif /* LINUX_VERSION >= 5.3 */ + }, #if defined(WL_CFG80211) && defined(DHD_FILE_DUMP_EVENT) { @@ -10010,7 +10747,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_SET_HAL_START }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_hal_started + .doit = wl_cfgvendor_set_hal_started, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = hal_start_attr_policy, + .maxattr = SET_HAL_START_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, { { @@ -10026,7 +10767,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = DEBUG_SET_HAL_PID }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_set_hal_pid + .doit = wl_cfgvendor_set_hal_pid, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = hal_start_attr_policy, + .maxattr = SET_HAL_START_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* WL_CFG80211 */ #ifdef WL_P2P_RAND @@ -10036,7 +10781,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = BRCM_VENDOR_SCMD_SET_MAC }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV, - .doit = wl_cfgvendor_set_p2p_rand_mac + .doit = wl_cfgvendor_set_p2p_rand_mac, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = brcm_drv_attr_policy, + .maxattr = BRCM_ATTR_DRIVER_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* WL_P2P_RAND */ #ifdef WL_THERMAL_MITIGATION @@ -10046,7 +10795,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_SUBCMD_THERMAL_MITIGATION }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgvendor_thermal_mitigation + .doit = wl_cfgvendor_thermal_mitigation, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_wifi_attr_policy, + .maxattr = ANDR_WIFI_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* WL_THERMAL_MITIGATION */ #ifdef WL_SAR_TX_POWER @@ -10056,7 +10809,11 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = WIFI_SUBCMD_TX_POWER_SCENARIO }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV, - .doit = wl_cfgvendor_tx_power_scenario + .doit = wl_cfgvendor_tx_power_scenario, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = andr_wifi_attr_policy, + .maxattr = ANDR_WIFI_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* WL_SAR_TX_POWER */ #ifdef WL_SOFTAP_ACS @@ -10066,9 +10823,39 @@ static struct wiphy_vendor_command wl_vendor_cmds [] = { .subcmd = BRCM_VENDOR_SCMD_ACS }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = wl_cfgscan_acs + .doit = wl_cfgscan_acs, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = acs_attr_policy, + .maxattr = BRCM_VENDOR_ATTR_ACS_LAST +#endif /* LINUX_VERSION >= 5.3 */ }, #endif /* WL_SOFTAP_ACS */ +#ifdef WL_CUSTOM_MAPPING_OF_DSCP + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = WIFI_SUBCMD_CUSTOM_MAPPING_OF_DSCP + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV, + .doit = wl_cfgvendor_custom_mapping_of_dscp, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = custom_setting_attr_policy, + .maxattr = CUSTOM_SETTING_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ + }, + { + { + .vendor_id = OUI_GOOGLE, + .subcmd = WIFI_SUBCMD_CUSTOM_MAPPING_OF_DSCP_RESET + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV, + .doit = wl_cfgvendor_custom_mapping_of_dscp_reset, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = custom_setting_attr_policy, + .maxattr = CUSTOM_SETTING_ATTRIBUTE_MAX +#endif /* LINUX_VERSION >= 5.3 */ + }, +#endif /* WL_CUSTOM_MAPPING_OF_DSCP */ }; static const struct nl80211_vendor_cmd_info wl_vendor_events [] = { @@ -10114,7 +10901,8 @@ static const struct nl80211_vendor_cmd_info wl_vendor_events [] = { { OUI_BRCM, BRCM_VENDOR_EVENT_WIPS}, { OUI_GOOGLE, NAN_ASYNC_RESPONSE_DISABLED}, { OUI_BRCM, BRCM_VENDOR_EVENT_RCC_INFO}, - { OUI_BRCM, BRCM_VENDOR_EVENT_ACS} + { OUI_BRCM, BRCM_VENDOR_EVENT_ACS}, + { OUI_BRCM, BRCM_VENDOR_EVENT_TWT} }; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) @@ -10126,7 +10914,9 @@ wl_cfgvendor_apply_cmd_policy(struct wiphy *wiphy) WL_INFORM(("Apply CMD_RAW_DATA policy\n")); for (i = 0; i < n_cmds; i++) { - wl_vendor_cmds[i].policy = VENDOR_CMD_RAW_DATA; + if (wl_vendor_cmds[i].policy == NULL) { + wl_vendor_cmds[i].policy = VENDOR_CMD_RAW_DATA; + } } } #endif /* LINUX VER >= 5.3 */ @@ -10158,6 +10948,9 @@ int wl_cfgvendor_attach(struct wiphy *wiphy, dhd_pub_t *dhd) #ifdef DHD_LOG_DUMP dhd_os_dbg_register_urgent_notifier(dhd, wl_cfgvendor_dbg_send_file_dump_evt); #endif /* DHD_LOG_DUMP */ +#ifdef WL_CUSTOM_MAPPING_OF_DSCP + (void)wl_set_dscp_deafult_priority(custom_dscp2priomap); +#endif return 0; } diff --git a/wl_cfgvendor.h b/wl_cfgvendor.h index c38b398..b510965 100644 --- a/wl_cfgvendor.h +++ b/wl_cfgvendor.h @@ -161,6 +161,9 @@ typedef enum { ANDROID_NL80211_SUBCMD_MITIGATION_RANGE_START = 0x1920, ANDROID_NL80211_SUBCMD_MITIGATION_RANGE_END = 0x192F, + /* define all customer related setting command between 0x2000 and 0x20FF */ + ANDROID_NL80211_SUBCMD_CUSTOM_SETTING_START = 0x2000, + ANDROID_NL80211_SUBCMD_CUSTOM_SETTING_END = 0x20FF, /* This is reserved for future usage */ } ANDROID_VENDOR_SUB_COMMAND; @@ -251,6 +254,8 @@ enum andr_vendor_subcmd { APF_SUBCMD_READ_FILTER_DATA, WIFI_SUBCMD_TX_POWER_SCENARIO = ANDROID_NL80211_SUBCMD_TX_POWER_RANGE_START, WIFI_SUBCMD_THERMAL_MITIGATION = ANDROID_NL80211_SUBCMD_MITIGATION_RANGE_START, + WIFI_SUBCMD_CUSTOM_MAPPING_OF_DSCP = ANDROID_NL80211_SUBCMD_CUSTOM_SETTING_START, + WIFI_SUBCMD_CUSTOM_MAPPING_OF_DSCP_RESET, /* Add more sub commands here */ VENDOR_SUBCMD_MAX }; @@ -393,33 +398,38 @@ enum gscan_ch_attributes { }; enum rtt_attributes { - RTT_ATTRIBUTE_TARGET_CNT, - RTT_ATTRIBUTE_TARGET_INFO, - RTT_ATTRIBUTE_TARGET_MAC, - RTT_ATTRIBUTE_TARGET_TYPE, - RTT_ATTRIBUTE_TARGET_PEER, - RTT_ATTRIBUTE_TARGET_CHAN, - RTT_ATTRIBUTE_TARGET_PERIOD, - RTT_ATTRIBUTE_TARGET_NUM_BURST, - RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST, - RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM, - RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR, - RTT_ATTRIBUTE_TARGET_LCI, - RTT_ATTRIBUTE_TARGET_LCR, - RTT_ATTRIBUTE_TARGET_BURST_DURATION, - RTT_ATTRIBUTE_TARGET_PREAMBLE, - RTT_ATTRIBUTE_TARGET_BW, - RTT_ATTRIBUTE_RESULTS_COMPLETE = 30, - RTT_ATTRIBUTE_RESULTS_PER_TARGET, - RTT_ATTRIBUTE_RESULT_CNT, - RTT_ATTRIBUTE_RESULT, - RTT_ATTRIBUTE_RESULT_DETAIL + RTT_ATTRIBUTE_INVALID = 0, + RTT_ATTRIBUTE_TARGET_CNT = 1, + RTT_ATTRIBUTE_TARGET_INFO = 2, + RTT_ATTRIBUTE_TARGET_MAC = 3, + RTT_ATTRIBUTE_TARGET_TYPE = 4, + RTT_ATTRIBUTE_TARGET_PEER = 5, + RTT_ATTRIBUTE_TARGET_CHAN = 6, + RTT_ATTRIBUTE_TARGET_PERIOD = 7, + RTT_ATTRIBUTE_TARGET_NUM_BURST = 8, + RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST = 9, + RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM = 10, + RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR = 11, + RTT_ATTRIBUTE_TARGET_LCI = 12, + RTT_ATTRIBUTE_TARGET_LCR = 13, + RTT_ATTRIBUTE_TARGET_BURST_DURATION = 14, + RTT_ATTRIBUTE_TARGET_PREAMBLE = 15, + RTT_ATTRIBUTE_TARGET_BW = 16, + RTT_ATTRIBUTE_RESULTS_COMPLETE = 30, + RTT_ATTRIBUTE_RESULTS_PER_TARGET = 31, + RTT_ATTRIBUTE_RESULT_CNT = 32, + RTT_ATTRIBUTE_RESULT = 33, + RTT_ATTRIBUTE_RESULT_DETAIL = 34, + /* Add any new RTT_ATTRIBUTE prior to RTT_ATTRIBUTE_MAX */ + RTT_ATTRIBUTE_MAX }; enum wifi_rssi_monitor_attr { - RSSI_MONITOR_ATTRIBUTE_MAX_RSSI, - RSSI_MONITOR_ATTRIBUTE_MIN_RSSI, - RSSI_MONITOR_ATTRIBUTE_START + RSSI_MONITOR_ATTRIBUTE_INVALID = 0, + RSSI_MONITOR_ATTRIBUTE_MAX_RSSI = 1, + RSSI_MONITOR_ATTRIBUTE_MIN_RSSI = 2, + RSSI_MONITOR_ATTRIBUTE_START = 3, + RSSI_MONITOR_ATTRIBUTE_MAX }; enum wifi_sae_key_attr { @@ -429,25 +439,28 @@ enum wifi_sae_key_attr { }; enum debug_attributes { - DEBUG_ATTRIBUTE_GET_DRIVER = 0, - DEBUG_ATTRIBUTE_GET_FW = 1, - DEBUG_ATTRIBUTE_RING_ID = 2, - DEBUG_ATTRIBUTE_RING_NAME = 3, - DEBUG_ATTRIBUTE_RING_FLAGS = 4, - DEBUG_ATTRIBUTE_LOG_LEVEL = 5, - DEBUG_ATTRIBUTE_LOG_TIME_INTVAL = 6, - DEBUG_ATTRIBUTE_LOG_MIN_DATA_SIZE = 7, - DEBUG_ATTRIBUTE_FW_DUMP_LEN = 8, - DEBUG_ATTRIBUTE_FW_DUMP_DATA = 9, - DEBUG_ATTRIBUTE_FW_ERR_CODE = 10, - DEBUG_ATTRIBUTE_RING_DATA = 11, - DEBUG_ATTRIBUTE_RING_STATUS = 12, - DEBUG_ATTRIBUTE_RING_NUM = 13, - DEBUG_ATTRIBUTE_DRIVER_DUMP_LEN = 14, - DEBUG_ATTRIBUTE_DRIVER_DUMP_DATA = 15, - DEBUG_ATTRIBUTE_PKT_FATE_NUM = 16, - DEBUG_ATTRIBUTE_PKT_FATE_DATA = 17, - DEBUG_ATTRIBUTE_HANG_REASON = 18 + DEBUG_ATTRIBUTE_INVALID = 0, + DEBUG_ATTRIBUTE_GET_DRIVER = 1, + DEBUG_ATTRIBUTE_GET_FW = 2, + DEBUG_ATTRIBUTE_RING_ID = 3, + DEBUG_ATTRIBUTE_RING_NAME = 4, + DEBUG_ATTRIBUTE_RING_FLAGS = 5, + DEBUG_ATTRIBUTE_LOG_LEVEL = 6, + DEBUG_ATTRIBUTE_LOG_TIME_INTVAL = 7, + DEBUG_ATTRIBUTE_LOG_MIN_DATA_SIZE = 8, + DEBUG_ATTRIBUTE_FW_DUMP_LEN = 9, + DEBUG_ATTRIBUTE_FW_DUMP_DATA = 10, + DEBUG_ATTRIBUTE_FW_ERR_CODE = 11, + DEBUG_ATTRIBUTE_RING_DATA = 12, + DEBUG_ATTRIBUTE_RING_STATUS = 13, + DEBUG_ATTRIBUTE_RING_NUM = 14, + DEBUG_ATTRIBUTE_DRIVER_DUMP_LEN = 15, + DEBUG_ATTRIBUTE_DRIVER_DUMP_DATA = 16, + DEBUG_ATTRIBUTE_PKT_FATE_NUM = 17, + DEBUG_ATTRIBUTE_PKT_FATE_DATA = 18, + DEBUG_ATTRIBUTE_HANG_REASON = 19, + /* Add new attributes just above this */ + DEBUG_ATTRIBUTE_MAX }; typedef enum { @@ -488,8 +501,11 @@ typedef enum { DUMP_LEN_ATTR_STATUS_LOG = 34, DUMP_LEN_ATTR_AXI_ERROR = 35, DUMP_FILENAME_ATTR_AXI_ERROR_DUMP = 36, - DUMP_LEN_ATTR_RTT_LOG = 37 + DUMP_LEN_ATTR_RTT_LOG = 37, + DUMP_LEN_ATTR_SDTC_ETB_DUMP = 38, + DUMP_FILENAME_ATTR_SDTC_ETB_DUMP = 39, /* Please add new attributes from here to sync up old HAL */ + DUMP_TYPE_ATTR_MAX } EWP_DUMP_EVENT_ATTRIBUTE; /* Attributes associated with DEBUG_GET_DUMP_BUF */ @@ -518,18 +534,30 @@ typedef enum { DUMP_BUF_ATTR_PKTLOG_DEBUG = 21, DUMP_BUF_ATTR_STATUS_LOG = 22, DUMP_BUF_ATTR_AXI_ERROR = 23, - DUMP_BUF_ATTR_RTT_LOG = 24 + DUMP_BUF_ATTR_RTT_LOG = 24, + DUMP_BUF_ATTR_SDTC_ETB_DUMP = 25, /* Please add new attributes from here to sync up old HAL */ + DUMP_BUF_ATTR_MAX } EWP_DUMP_CMD_ATTRIBUTE; enum mkeep_alive_attributes { - MKEEP_ALIVE_ATTRIBUTE_ID, - MKEEP_ALIVE_ATTRIBUTE_IP_PKT, - MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN, - MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR, - MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR, - MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC, - MKEEP_ALIVE_ATTRIBUTE_ETHER_TYPE + MKEEP_ALIVE_ATTRIBUTE_INVALID = 0, + MKEEP_ALIVE_ATTRIBUTE_ID = 1, + MKEEP_ALIVE_ATTRIBUTE_IP_PKT = 2, + MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN = 3, + MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR = 4, + MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR = 5, + MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC = 6, + MKEEP_ALIVE_ATTRIBUTE_ETHER_TYPE = 7, + MKEEP_ALIVE_ATTRIBUTE_MAX +}; + +enum custom_setting_attributes { + CUSTOM_SETTING_ATTRIBUTE_INVALID = 0, + CUSTOM_SETTING_ATTRIBUTE_DSCP_START = 1, + CUSTOM_SETTING_ATTRIBUTE_DSCP_END = 2, + CUSTOM_SETTING_ATTRIBUTE_ACCESS_CATEGORY = 3, + CUSTOM_SETTING_ATTRIBUTE_MAX }; typedef enum wl_vendor_event { @@ -582,6 +610,7 @@ typedef enum wl_vendor_event { NAN_ASYNC_RESPONSE_DISABLED = 40, BRCM_VENDOR_EVENT_RCC_INFO = 41, BRCM_VENDOR_EVENT_ACS = 42, + BRCM_VENDOR_EVENT_TWT = 43, BRCM_VENDOR_EVENT_LAST } wl_vendor_event_t; @@ -597,13 +626,16 @@ enum andr_wifi_attr { ANDR_WIFI_ATTRIBUTE_RANDOM_MAC, ANDR_WIFI_ATTRIBUTE_TX_POWER_SCENARIO, ANDR_WIFI_ATTRIBUTE_THERMAL_MITIGATION, - ANDR_WIFI_ATTRIBUTE_THERMAL_COMPLETION_WINDOW + ANDR_WIFI_ATTRIBUTE_THERMAL_COMPLETION_WINDOW, + /* Any new ANDR_WIFI attribute add prior to the ANDR_WIFI_ATTRIBUTE_MAX */ + ANDR_WIFI_ATTRIBUTE_MAX }; enum apf_attributes { APF_ATTRIBUTE_VERSION, APF_ATTRIBUTE_MAX_LEN, APF_ATTRIBUTE_PROGRAM, - APF_ATTRIBUTE_PROGRAM_LEN + APF_ATTRIBUTE_PROGRAM_LEN, + APF_ATTRIBUTE_MAX }; typedef enum wl_vendor_gscan_attribute { @@ -656,7 +688,8 @@ enum wake_stat_attributes { WAKE_STAT_ATTRIBUTE_RX_ICMP6_NS, WAKE_STAT_ATTRIBUTE_IPV4_RX_MULTICAST_ADD_CNT, WAKE_STAT_ATTRIBUTE_IPV6_RX_MULTICAST_ADD_CNT, - WAKE_STAT_ATTRIBUTE_OTHER_RX_MULTICAST_ADD_CNT + WAKE_STAT_ATTRIBUTE_OTHER_RX_MULTICAST_ADD_CNT, + WAKE_STAT_ATTRIBUTE_MAX }; typedef struct rx_data_cnt_details_t { @@ -723,7 +756,9 @@ typedef struct wifi_roaming_capabilities { typedef enum { SET_HAL_START_ATTRIBUTE_DEINIT = 0x0001, SET_HAL_START_ATTRIBUTE_PRE_INIT = 0x0002, - SET_HAL_START_ATTRIBUTE_EVENT_SOCK_PID = 0x0003 + SET_HAL_START_ATTRIBUTE_EVENT_SOCK_PID = 0x0003, + /* Add any new HAL_START attribute prior to SET_HAL_START_ATTRIBUTE_MAX */ + SET_HAL_START_ATTRIBUTE_MAX } SET_HAL_START_ATTRIBUTE; #ifdef WL_THERMAL_MITIGATION @@ -745,6 +780,34 @@ typedef enum { #define DUTY_CYCLE_EMERGENCY 10u #endif /* WL_THERMAL_MITIGATION */ +#ifdef WL_TWT +typedef enum { + WIFI_TWT_EVENT_SETUP = 1, + WIFI_TWT_EVENT_TEARDOWN = 2, + WIFI_TWT_EVENT_INFO_FRM = 3 +} wifi_twt_sub_event; +typedef enum { + WIFI_TWT_ATTR_NONE = 0, + WIFI_TWT_ATTR_SUB_EVENT = 1, + WIFI_TWT_ATTR_REASON_CODE = 2, + WIFI_TWT_ATTR_STATUS = 3, + WIFI_TWT_ATTR_SETUP_CMD = 4, + WIFI_TWT_ATTR_FLOW_FLAGS = 5, + WIFI_TWT_ATTR_FLOW_ID = 6, + WIFI_TWT_ATTR_CHANNEL = 7, + WIFI_TWT_ATTR_NEGOTIATION_TYPE = 8, + WIFI_TWT_ATTR_WAKETIME_H = 9, + WIFI_TWT_ATTR_WAKETIME_L = 10, + WIFI_TWT_ATTR_WAKE_DURATION = 11, + WIFI_TWT_ATTR_WAKE_INTERVAL = 12, + WIFI_TWT_ATTR_BID = 13, + WIFI_TWT_ATTR_ALLTWT = 14, + WIFI_TWT_ATTR_NEXT_TWT_H = 15, + WIFI_TWT_ATTR_NEXT_TWT_L = 16, + WIFI_TWT_ATTR_MAX +} wifi_twt_attribute; +#endif /* WL_TWT */ + /* Capture the BRCM_VENDOR_SUBCMD_PRIV_STRINGS* here */ #define BRCM_VENDOR_SCMD_CAPA "cap" #define MEMDUMP_PATH_LEN 128 diff --git a/wl_cfgvif.c b/wl_cfgvif.c index 1ad6c09..0e6f990 100644 --- a/wl_cfgvif.c +++ b/wl_cfgvif.c @@ -477,7 +477,6 @@ wl_cfg80211_get_iface_policy(struct net_device *ndev) #endif /* WL_IFACE_MGMT */ #endif /* WL_IFACE_MGMT_CONF */ -#ifdef WL_IFACE_MGMT /* Get active secondary data iface type */ wl_iftype_t wl_cfg80211_get_sec_iface(struct bcm_cfg80211 *cfg) @@ -528,6 +527,7 @@ wl_cfg80211_get_sec_iface(struct bcm_cfg80211 *cfg) return WL_IFACE_NOT_PRESENT; } +#ifdef WL_IFACE_MGMT /* * Handle incoming data interface request based on policy. * If there is any conflicting interface, that will be @@ -834,12 +834,13 @@ wl_cfg80211_handle_if_role_conflict(struct bcm_cfg80211 *cfg, { s32 ret = BCME_OK; - WL_INFORM_MEM(("Incoming iface = %s\n", wl_iftype_to_str(new_wl_iftype))); + WL_DBG_MEM(("Incoming iface = %s\n", wl_iftype_to_str(new_wl_iftype))); if (!is_discovery_iface(new_wl_iftype)) { /* Incoming data interface request */ if (wl_cfg80211_get_sec_iface(cfg) != WL_IFACE_NOT_PRESENT) { /* active interface present - Apply interface data policy */ + WL_INFORM_MEM(("apply iface policy for %d\n", new_wl_iftype)); ret = wl_cfg80211_data_if_mgmt(cfg, new_wl_iftype); if (ret != BCME_OK) { WL_ERR(("if_mgmt fail:%d\n", ret)); diff --git a/wl_cfgvif.h b/wl_cfgvif.h index 9657450..6e595af 100644 --- a/wl_cfgvif.h +++ b/wl_cfgvif.h @@ -115,11 +115,11 @@ void wl_cfg80211_init_ap_rps(struct bcm_cfg80211 *cfg); int wl_cfg80211_iface_count(struct net_device *dev); struct net_device* wl_get_ap_netdev(struct bcm_cfg80211 *cfg, char *ifname); void wl_cfg80211_cleanup_virtual_ifaces(struct bcm_cfg80211 *cfg, bool rtnl_lock_reqd); +extern wl_iftype_t wl_cfg80211_get_sec_iface(struct bcm_cfg80211 *cfg); #ifdef WL_IFACE_MGMT extern int wl_cfg80211_set_iface_policy(struct net_device *ndev, char *arg, int len); extern uint8 wl_cfg80211_get_iface_policy(struct net_device *ndev); extern s32 wl_cfg80211_handle_if_role_conflict(struct bcm_cfg80211 *cfg, wl_iftype_t new_wl_iftype); -extern wl_iftype_t wl_cfg80211_get_sec_iface(struct bcm_cfg80211 *cfg); #endif /* WL_IFACE_MGMT */ extern s32 wl_get_vif_macaddr(struct bcm_cfg80211 *cfg, u16 wl_iftype, u8 *mac_addr); |