net: wireless: update bcmdhd driver to "1.579.77.41.9 (r)"

Change-Id: I5b5a30393157192fd8c1c033169931e7d5b03df0
Signed-off-by: Yao Xiao <xiaoyao@rock-chips.com>
This commit is contained in:
Yao Xiao 2018-09-04 09:09:18 +08:00 committed by Tao Huang
parent f8df3865b8
commit 3c66f60d13
52 changed files with 14248 additions and 3350 deletions

View File

@ -38,6 +38,9 @@ config BCMDHD_SDIO
config BCMDHD_PCIE
bool "PCIe bus interface support"
depends on BCMDHD && PCI
config BCMDHD_USB
bool "USB bus interface support"
depends on BCMDHD && USB
endchoice
choice

View File

@ -6,122 +6,165 @@
MODULE_NAME = bcmdhd
CONFIG_BCMDHD_SDIO := y
#CONFIG_BCMDHD_PCIE := y
#CONFIG_BCMDHD_USB := y
CONFIG_BCMDHD_OOB := y
CONFIG_BCMDHD_PROPTXSTATUS := y
CONFIG_BCMDHD_AG := y
#CONFIG_DHD_USE_STATIC_BUF := y
CONFIG_VTS_SUPPORT := y
#CONFIG_LOGTRACE := y
DHDCFLAGS = -Wall -Wstrict-prototypes -Dlinux -DBCMDRIVER -DSDTEST \
CONFIG_MACH_PLATFORM := y
#CONFIG_BCMDHD_DTS := y
DHDCFLAGS = -Wall -Wstrict-prototypes -Dlinux -DBCMDRIVER \
-DBCMDONGLEHOST -DUNRELEASEDCHIP -DBCMDMA32 -DBCMFILEIMAGE \
-DDHDTHREAD -DDHD_DEBUG -DSHOW_EVENTS -DBCMDBG -DGET_OTP_MAC_ENABLE \
-DWIFI_ACT_FRAME -DARP_OFFLOAD_SUPPORT -DSUPPORT_PM2_ONLY \
-DKEEP_ALIVE -DPKT_FILTER_SUPPORT -DPNO_SUPPORT -DDHDTCPACK_SUPPRESS \
-DDHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT -DRXFRAME_THREAD \
-DTSQ_MULTIPLIER -DMFP -DWL_EXT_IAPSTA \
-DDHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT \
-DMULTIPLE_SUPPLICANT -DTSQ_MULTIPLIER -DMFP \
-DWL_EXT_IAPSTA \
-DENABLE_INSMOD_NO_FW_LOAD -DDHD_UNSUPPORT_IF_CNTS \
-Idrivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd \
-Idrivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include
DHDOFILES = aiutils.o siutils.o sbutils.o bcmutils.o bcmwifi_channels.o \
dhd_linux.o dhd_linux_platdev.o dhd_linux_sched.o dhd_pno.o \
dhd_common.o dhd_ip.o dhd_linux_wq.o dhd_custom_gpio.o \
bcmevent.o hndpmu.o linux_osl.o wldev_common.o wl_android.o \
DHDOFILES = aiutils.o siutils.o sbutils.o bcmutils.o bcmwifi_channels.o \
dhd_linux.o dhd_linux_platdev.o dhd_linux_sched.o dhd_pno.o \
dhd_common.o dhd_ip.o dhd_linux_wq.o dhd_custom_gpio.o \
bcmevent.o hndpmu.o linux_osl.o wldev_common.o wl_android.o \
hnd_pktq.o hnd_pktpool.o dhd_config.o wl_android_ext.o
#BCMDHD_SDIO
ifneq ($(CONFIG_BCMDHD_SDIO),)
DHDCFLAGS += \
-DBCMSDIO -DMMC_SDIO_ABORT -DBCMLXSDMMC -DUSE_SDIOFIFO_IOVAR \
-DBDC -DDHD_USE_IDLECOUNT -DBCMSDIOH_TXGLOM -DBCMSDIOH_TXGLOM_EXT \
-DCUSTOM_SDIO_F2_BLKSIZE=256
DHDOFILES += bcmsdh.o bcmsdh_linux.o bcmsdh_sdmmc.o bcmsdh_sdmmc_linux.o \
dhd_sdio.o dhd_cdc.o dhd_wlfc.o
DHDCFLAGS += -DBCMSDIO -DMMC_SDIO_ABORT -DBCMLXSDMMC -DUSE_SDIOFIFO_IOVAR \
-DSDTEST -DBDC -DDHD_USE_IDLECOUNT -DCUSTOM_SDIO_F2_BLKSIZE=256 \
-DBCMSDIOH_TXGLOM -DBCMSDIOH_TXGLOM_EXT -DRXFRAME_THREAD
ifeq ($(CONFIG_BCMDHD_OOB),y)
DHDCFLAGS += -DOOB_INTR_ONLY -DCUSTOMER_OOB -DHW_OOB
DHDCFLAGS += -DOOB_INTR_ONLY -DCUSTOMER_OOB -DHW_OOB
ifeq ($(CONFIG_BCMDHD_DISABLE_WOWLAN),y)
DHDCFLAGS += -DDISABLE_WOWLAN
DHDCFLAGS += -DDISABLE_WOWLAN
endif
else
DHDCFLAGS += -DSDIO_ISR_THREAD
endif
DHDCFLAGS += -DSDIO_ISR_THREAD
endif
ifeq ($(CONFIG_BCMDHD_PROPTXSTATUS),y)
ifneq ($(CONFIG_BCMDHD_SDIO),)
DHDCFLAGS += -DPROP_TXSTATUS
endif
ifneq ($(CONFIG_CFG80211),)
DHDCFLAGS += -DPROP_TXSTATUS_VSDB
endif
DHDOFILES += bcmsdh.o bcmsdh_linux.o bcmsdh_sdmmc.o bcmsdh_sdmmc_linux.o \
dhd_sdio.o dhd_cdc.o dhd_wlfc.o
endif
#BCMDHD_PCIE
ifneq ($(CONFIG_BCMDHD_PCIE),)
DHDCFLAGS += \
-DPCIE_FULL_DONGLE -DBCMPCIE -DCUSTOM_DPC_PRIO_SETTING=-1
DHDCFLAGS += -DPCIE_FULL_DONGLE -DBCMPCIE -DCUSTOM_DPC_PRIO_SETTING=-1 \
-DDONGLE_ENABLE_ISOLATION
ifneq ($(CONFIG_PCI_MSI),)
DHDCFLAGS += -DDHD_USE_MSI
endif
ifeq ($(CONFIG_DHD_USE_STATIC_BUF),y)
DHDCFLAGS += -DDHD_USE_STATIC_CTRLBUF
DHDCFLAGS += -DDHD_USE_STATIC_CTRLBUF
endif
DHDOFILES += dhd_pcie.o dhd_pcie_linux.o pcie_core.o dhd_flowring.o \
DHDOFILES += dhd_pcie.o dhd_pcie_linux.o pcie_core.o dhd_flowring.o \
dhd_msgbuf.o
endif
ifeq ($(CONFIG_VTS_SUPPORT),y)
DHDCFLAGS += \
-DGSCAN_SUPPORT -DRTT_SUPPORT -DCUSTOM_FORCE_NODFS_FLAG \
-DLINKSTAT_SUPPORT -DDEBUGABILITY -DDBG_PKT_MON -DKEEP_ALIVE -DPKT_FILTER_SUPPORT \
-DAPF -DNDO_CONFIG_SUPPORT -DRSSI_MONITOR_SUPPORT -DDHDTCPACK_SUPPRESS -DDHD_WAKE_STATUS \
-DCUSTOM_COUNTRY_CODE -DDHD_FW_COREDUMP -DEXPLICIT_DISCIF_CLEANUP
#BCMDHD_USB
ifneq ($(CONFIG_BCMDHD_USB),)
DHDCFLAGS += -DUSBOS_TX_THREAD -DBCMDBUS -DBCMTRXV2 -DDBUS_USB_LOOPBACK \
-DBDC
DHDCFLAGS += -DBCM_REQUEST_FW -DEXTERNAL_FW_PATH
#DHDCFLAGS :=$(filter-out -DENABLE_INSMOD_NO_FW_LOAD,$(DHDCFLAGS))
DHDOFILES += dhd_debug_linux.o dhd_debug.o bcmxtlv.o \
dhd_rtt.o bcm_app_utils.o
DHDOFILES += dbus.o dbus_usb.o dbus_usb_linux.o dhd_cdc.o dhd_wlfc.o
endif
ifeq ($(CONFIG_BCMDHD_PROPTXSTATUS),y)
ifneq ($(CONFIG_BCMDHD_USB),)
DHDCFLAGS += -DPROP_TXSTATUS
endif
ifneq ($(CONFIG_BCMDHD_SDIO),)
DHDCFLAGS += -DPROP_TXSTATUS
endif
ifneq ($(CONFIG_CFG80211),)
DHDCFLAGS += -DPROP_TXSTATUS_VSDB
endif
endif
#VTS_SUPPORT
ifeq ($(CONFIG_VTS_SUPPORT),y)
ifneq ($(CONFIG_CFG80211),)
DHDCFLAGS += -DGSCAN_SUPPORT -DRTT_SUPPORT -DCUSTOM_FORCE_NODFS_FLAG \
-DLINKSTAT_SUPPORT -DDEBUGABILITY -DDBG_PKT_MON -DPKT_FILTER_SUPPORT \
-DAPF -DNDO_CONFIG_SUPPORT -DRSSI_MONITOR_SUPPORT -DDHD_WAKE_STATUS \
-DCUSTOM_COUNTRY_CODE -DDHD_FW_COREDUMP -DEXPLICIT_DISCIF_CLEANUP
DHDOFILES += bcmxtlv.o dhd_rtt.o bcm_app_utils.o
CONFIG_LOGTRACE := y
endif
endif
#LOGTRACE
ifeq ($(CONFIG_LOGTRACE),y)
DHDCFLAGS += -DSHOW_LOGTRACE
DHDOFILES += dhd_debug_linux.o dhd_debug.o dhd_mschdbg.o
endif
# MESH support for kernel 3.10 later
ifeq ($(CONFIG_WL_MESH),y)
DHDCFLAGS += -DWLMESH
ifneq ($(CONFIG_BCMDHD_PCIE),)
DHDCFLAGS += -DBCM_HOST_BUF -DDMA_HOST_BUFFER_LEN=0x80000
endif
DHDCFLAGS += -DDHD_UPDATE_INTF_MAC
DHDCFLAGS :=$(filter-out -DDHD_FW_COREDUMP,$(DHDCFLAGS))
DHDCFLAGS :=$(filter-out -DSET_RANDOM_MAC_SOFTAP,$(DHDCFLAGS))
endif
#obj-$(CONFIG_RKWIFI) += bcmdhd.o
obj-$(CONFIG_AP6XXX) += bcmdhd.o
bcmdhd-objs += $(DHDOFILES)
#ifeq ($(CONFIG_MACH_PLATFORM),y)
DHDOFILES += dhd_gpio.o
DHDCFLAGS += -DCUSTOMER_HW -DDHD_OF_SUPPORT
#DHDCFLAGS += -DBCMWAPI_WPI -DBCMWAPI_WAI
#endif
ifeq ($(CONFIG_MACH_PLATFORM),y)
DHDOFILES += dhd_gpio.o
ifeq ($(CONFIG_BCMDHD_DTS),y)
DHDCFLAGS += -DCONFIG_DTS
else
DHDCFLAGS += -DCUSTOMER_HW -DDHD_OF_SUPPORT
endif
# DHDCFLAGS += -DBCMWAPI_WPI -DBCMWAPI_WAI
endif
ifeq ($(CONFIG_BCMDHD_AG),y)
DHDCFLAGS += -DBAND_AG
DHDCFLAGS += -DBAND_AG
endif
ifeq ($(CONFIG_DHD_USE_STATIC_BUF),y)
obj-m += dhd_static_buf.o
DHDCFLAGS += -DSTATIC_WL_PRIV_STRUCT -DENHANCED_STATIC_BUF
DHDCFLAGS += -DDHD_USE_STATIC_MEMDUMP -DCONFIG_DHD_USE_STATIC_BUF
obj-m += dhd_static_buf.o
DHDCFLAGS += -DSTATIC_WL_PRIV_STRUCT -DENHANCED_STATIC_BUF
DHDCFLAGS += -DDHD_USE_STATIC_MEMDUMP -DCONFIG_DHD_USE_STATIC_BUF
endif
ifneq ($(CONFIG_WIRELESS_EXT),)
DHDOFILES += wl_iw.o wl_escan.o
DHDCFLAGS += -DSOFTAP -DWL_WIRELESS_EXT -DUSE_IW -DWL_ESCAN
DHDOFILES += wl_iw.o wl_escan.o
DHDCFLAGS += -DSOFTAP -DWL_WIRELESS_EXT -DUSE_IW -DWL_ESCAN
endif
ifneq ($(CONFIG_CFG80211),)
DHDOFILES += wl_cfg80211.o wl_cfgp2p.o wl_linux_mon.o wl_cfg_btcoex.o wl_cfgvendor.o
DHDOFILES += dhd_cfg80211.o
DHDCFLAGS += -DWL_CFG80211 -DWLP2P -DWL_CFG80211_STA_EVENT -DWL_ENABLE_P2P_IF
#DHDCFLAGS += -DWL_IFACE_COMB_NUM_CHANNELS
DHDCFLAGS += -DCUSTOM_ROAM_TRIGGER_SETTING=-65
DHDCFLAGS += -DCUSTOM_ROAM_DELTA_SETTING=15
DHDCFLAGS += -DCUSTOM_KEEP_ALIVE_SETTING=28000
DHDCFLAGS += -DCUSTOM_PNO_EVENT_LOCK_xTIME=7
DHDCFLAGS += -DWL_SUPPORT_AUTO_CHANNEL
DHDCFLAGS += -DWL_SUPPORT_BACKPORTED_KPATCHES
DHDCFLAGS += -DESCAN_RESULT_PATCH
DHDCFLAGS += -DVSDB -DWL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
DHDCFLAGS += -DWLTDLS -DMIRACAST_AMPDU_SIZE=8
DHDCFLAGS += -DWL_VIRTUAL_APSTA
DHDOFILES += wl_cfg80211.o wl_cfgp2p.o wl_linux_mon.o wl_cfg_btcoex.o wl_cfgvendor.o
DHDOFILES += dhd_cfg80211.o
DHDCFLAGS += -DWL_CFG80211 -DWLP2P -DWL_CFG80211_STA_EVENT -DWL_ENABLE_P2P_IF
# DHDCFLAGS += -DWL_IFACE_COMB_NUM_CHANNELS
DHDCFLAGS += -DCUSTOM_ROAM_TRIGGER_SETTING=-65
DHDCFLAGS += -DCUSTOM_ROAM_DELTA_SETTING=15
DHDCFLAGS += -DCUSTOM_KEEP_ALIVE_SETTING=28000
DHDCFLAGS += -DCUSTOM_PNO_EVENT_LOCK_xTIME=7
DHDCFLAGS += -DWL_SUPPORT_AUTO_CHANNEL
DHDCFLAGS += -DWL_SUPPORT_BACKPORTED_KPATCHES
DHDCFLAGS += -DESCAN_RESULT_PATCH -DESCAN_BUF_OVERFLOW_MGMT
DHDCFLAGS += -DVSDB -DWL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
DHDCFLAGS += -DWLTDLS -DMIRACAST_AMPDU_SIZE=8
DHDCFLAGS += -DWL_VIRTUAL_APSTA
endif
EXTRA_CFLAGS = $(DHDCFLAGS)
ifeq ($(CONFIG_BCMDHD),m)
DHDCFLAGS += -DMULTIPLE_SUPPLICANT
EXTRA_LDFLAGS += --strip-debug
else
DHDCFLAGS += -DBUILD_IN_KERNEL
endif

View File

@ -52,7 +52,6 @@ extern void dhdsdio_isr(void * args);
#endif /* defined(CONFIG_ARCH_ODIN) */
#include <dhd_linux.h>
/* driver info, initialized when bcmsdh_register is called */
static bcmsdh_driver_t drvinfo = {NULL, NULL, NULL, NULL};
@ -363,13 +362,13 @@ int bcmsdh_oob_intr_register(bcmsdh_info_t *bcmsdh, bcmsdh_cb_fn_t oob_irq_handl
SDLX_MSG(("%s: irq is already registered\n", __FUNCTION__));
return -EBUSY;
}
SDLX_MSG(("%s %s irq=%d flags=0x%X\n", __FUNCTION__,
#ifdef HW_OOB
"HW_OOB",
printf("%s: HW_OOB irq=%d flags=0x%X\n", __FUNCTION__,
(int)bcmsdh_osinfo->oob_irq_num, (int)bcmsdh_osinfo->oob_irq_flags);
#else
"SW_OOB",
printf("%s: SW_OOB irq=%d flags=0x%X\n", __FUNCTION__,
(int)bcmsdh_osinfo->oob_irq_num, (int)bcmsdh_osinfo->oob_irq_flags);
#endif
(int)bcmsdh_osinfo->oob_irq_num, (int)bcmsdh_osinfo->oob_irq_flags));
bcmsdh_osinfo->oob_irq_handler = oob_irq_handler;
bcmsdh_osinfo->oob_irq_handler_context = oob_irq_handler_context;
bcmsdh_osinfo->oob_irq_enabled = TRUE;
@ -398,6 +397,7 @@ int bcmsdh_oob_intr_register(bcmsdh_info_t *bcmsdh, bcmsdh_cb_fn_t oob_irq_handl
else
bcmsdh_osinfo->oob_irq_wake_enabled = TRUE;
#endif
return 0;
}
@ -423,7 +423,7 @@ void bcmsdh_oob_intr_unregister(bcmsdh_info_t *bcmsdh)
free_irq(bcmsdh_osinfo->oob_irq_num, bcmsdh);
bcmsdh_osinfo->oob_irq_registered = FALSE;
}
#endif
#endif
/* Module parameters specific to each host-controller driver */

View File

@ -995,7 +995,6 @@ sdioh_set_mode(sdioh_info_t *sd, uint mode)
sd->txglom_mode = mode;
else if (mode == SDPCM_TXGLOM_MDESC)
sd->txglom_mode = mode;
printf("%s: set txglom_mode to %s\n", __FUNCTION__, mode==SDPCM_TXGLOM_MDESC?"multi-desc":"copy");
return (sd->txglom_mode);
}
@ -1288,8 +1287,8 @@ sdioh_request_packet_chain(sdioh_info_t *sd, uint fix_inc, uint write, uint func
if (sd_msglevel & SDH_COST_VAL) {
getnstimeofday(&now);
sd_cost(("%s: rw=%d, cost=%lds %luus\n", __FUNCTION__,
write, now.tv_sec-before.tv_sec, now.tv_nsec/1000-before.tv_nsec/1000));
sd_cost(("%s: rw=%d, ttl_len=%d, cost=%lds %luus\n", __FUNCTION__,
write, ttl_len, now.tv_sec-before.tv_sec, now.tv_nsec/1000-before.tv_nsec/1000));
}
sd_trace(("%s: Exit\n", __FUNCTION__));

View File

@ -232,7 +232,7 @@ static const struct sdio_device_id bcmsdh_sdmmc_ids[] = {
MODULE_DEVICE_TABLE(sdio, bcmsdh_sdmmc_ids);
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM_SLEEP)
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM)
static int bcmsdh_sdmmc_suspend(struct device *pdev)
{
int err;
@ -275,9 +275,7 @@ static int bcmsdh_sdmmc_suspend(struct device *pdev)
static int bcmsdh_sdmmc_resume(struct device *pdev)
{
#if defined(OOB_INTR_ONLY)
sdioh_info_t *sdioh;
#endif
struct sdio_func *func = dev_to_sdio_func(pdev);
printf("%s Enter func->num=%d\n", __FUNCTION__, func->num);
@ -285,10 +283,8 @@ static int bcmsdh_sdmmc_resume(struct device *pdev)
return 0;
dhd_mmc_suspend = FALSE;
#if defined(OOB_INTR_ONLY)
sdioh = sdio_get_drvdata(func);
bcmsdh_resume(sdioh->bcmsdh);
#endif
smp_mb();
printf("%s Exit\n", __FUNCTION__);
@ -346,7 +342,7 @@ static struct sdio_driver bcmsdh_sdmmc_driver = {
.remove = bcmsdh_sdmmc_remove,
.name = "bcmsdh_sdmmc",
.id_table = bcmsdh_sdmmc_ids,
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM_SLEEP)
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM)
.drv = {
.pm = &bcmsdh_sdmmc_pm_ops,
},

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -51,6 +51,9 @@
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK)
#include <linux/wakelock.h>
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_HAS_WAKELOCK) */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
#include <linux/sched/types.h>
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
/* The kernel threading is sdio-specific */
struct task_struct;
struct sched_param;
@ -106,6 +109,7 @@ enum dhd_bus_state {
DHD_BUS_DATA, /* Ready for frame transfers */
DHD_BUS_SUSPEND, /* Bus has been suspended */
DHD_BUS_DOWN_IN_PROGRESS, /* Bus going Down */
DHD_BUS_REMOVE, /* Bus has been removed */
};
/*
@ -217,7 +221,11 @@ enum dhd_bus_state {
DHD_BUS_BUSY_CHECK_RPM_SUSPEND_IN_PROGRESS(dhdp))
#define DHD_BUS_CHECK_DOWN_OR_DOWN_IN_PROGRESS(dhdp) \
((dhdp)->busstate == DHD_BUS_DOWN || (dhdp)->busstate == DHD_BUS_DOWN_IN_PROGRESS)
((dhdp)->busstate == DHD_BUS_DOWN || (dhdp)->busstate == DHD_BUS_DOWN_IN_PROGRESS || \
(dhdp)->busstate == DHD_BUS_REMOVE)
#define DHD_BUS_CHECK_REMOVE(dhdp) \
((dhdp)->busstate == DHD_BUS_REMOVE)
/* Macro to print Ethernet Address as String
* expects both arguements as (char *)
@ -667,6 +675,9 @@ typedef struct dhd_pub {
* please do NOT merge it back from other branches !!!
*/
#ifdef BCMDBUS
struct dbus_pub *dbus;
#endif /* BCMDBUS */
/* Internal dhd items */
bool up; /* Driver up/down (to OS) */
@ -1028,6 +1039,10 @@ typedef struct dhd_pub {
char *clm_path; /* module_param: path to clm vars file */
char *conf_path; /* module_param: path to config vars file */
struct dhd_conf *conf; /* Bus module handle */
void *adapter; /* adapter information, interrupt, fw path etc. */
#ifdef BCMDBUS
bool dhd_remove;
#endif /* BCMDBUS */
} dhd_pub_t;
typedef struct {
@ -1347,12 +1362,36 @@ typedef enum dhd_ioctl_recieved_status
*/
void dhd_net_if_lock(struct net_device *dev);
void dhd_net_if_unlock(struct net_device *dev);
#if defined(MULTIPLE_SUPPLICANT)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
extern struct mutex _dhd_sdio_mutex_lock_;
extern void wl_android_post_init(void); // terence 20120530: fix critical section in dhd_open and dhdsdio_probe
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && defined(MULTIPLE_SUPPLICANT)
extern struct mutex _dhd_mutex_lock_;
#define DHD_MUTEX_IS_LOCK_RETURN() \
if (mutex_is_locked(&_dhd_mutex_lock_) != 0) { \
printf("%s : probe is already running! return.\n", __FUNCTION__); \
return 0; \
}
#define DHD_MUTEX_LOCK() \
do { \
if (mutex_is_locked(&_dhd_mutex_lock_) == 0) { \
printf("%s : no mutex held. set lock\n", __FUNCTION__); \
} else { \
printf("%s : mutex is locked!. wait for unlocking\n", __FUNCTION__); \
} \
mutex_lock(&_dhd_mutex_lock_); \
} while (0)
#define DHD_MUTEX_UNLOCK() \
do { \
mutex_unlock(&_dhd_mutex_lock_); \
printf("%s : the lock is released.\n", __FUNCTION__); \
} while (0)
#else
#define DHD_MUTEX_IS_LOCK_RETURN(a) do {} while (0)
#define DHD_MUTEX_LOCK(a) do {} while (0)
#define DHD_MUTEX_UNLOCK(a) do {} while (0)
#endif
#endif /* MULTIPLE_SUPPLICANT */
typedef enum dhd_attach_states
{
@ -1386,7 +1425,11 @@ typedef enum dhd_attach_states
* Returned structure should have bus and prot pointers filled in.
* bus_hdrlen specifies required headroom for bus module header.
*/
extern dhd_pub_t *dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen);
extern dhd_pub_t *dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen
#ifdef BCMDBUS
, void *adapter
#endif
);
#if defined(WLP2P) && defined(WL_CFG80211)
/* To allow attach/detach calls corresponding to p2p0 interface */
extern int dhd_attach_p2p(dhd_pub_t *);
@ -1482,7 +1525,7 @@ extern void dhd_os_dhdiovar_lock(dhd_pub_t *pub);
extern void dhd_os_dhdiovar_unlock(dhd_pub_t *pub);
extern int dhd_os_proto_block(dhd_pub_t * pub);
extern int dhd_os_proto_unblock(dhd_pub_t * pub);
extern int dhd_os_ioctl_resp_wait(dhd_pub_t * pub, uint * condition);
extern int dhd_os_ioctl_resp_wait(dhd_pub_t * pub, uint * condition, bool resched);
extern int dhd_os_ioctl_resp_wake(dhd_pub_t * pub);
extern unsigned int dhd_os_get_ioctl_resp_timeout(void);
extern void dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec);
@ -1700,6 +1743,9 @@ extern int dhd_event_ifdel(struct dhd_info *dhd, struct wl_event_data_if *ifeven
char *name, uint8 *mac);
extern int dhd_event_ifchange(struct dhd_info *dhd, struct wl_event_data_if *ifevent,
char *name, uint8 *mac);
#ifdef DHD_UPDATE_INTF_MAC
extern int dhd_op_if_update(dhd_pub_t *dhdpub, int ifidx);
#endif /* DHD_UPDATE_INTF_MAC */
extern struct net_device* dhd_allocate_if(dhd_pub_t *dhdpub, int ifidx, const char *name,
uint8 *mac, uint8 bssidx, bool need_rtnl_lock, const char *dngl_name);
extern int dhd_remove_if(dhd_pub_t *dhdpub, int ifidx, bool need_rtnl_lock);
@ -1821,6 +1867,9 @@ extern uint dhd_console_ms;
extern uint android_msg_level;
extern uint config_msg_level;
extern uint sd_msglevel;
#ifdef BCMDBUS
extern uint dbus_msglevel;
#endif /* BCMDBUS */
#ifdef WL_WIRELESS_EXT
extern uint iw_msg_level;
#endif
@ -2031,7 +2080,9 @@ extern char fw_path2[MOD_PARAM_PATHLEN];
/* Flag to indicate if we should download firmware on driver load */
extern uint dhd_download_fw_on_driverload;
#ifndef BCMDBUS
extern int allow_delay_fwdl;
#endif /* !BCMDBUS */
extern int dhd_process_cid_mac(dhd_pub_t *dhdp, bool prepost);
extern int dhd_write_file(const char *filepath, char *buf, int buf_len);
@ -2226,6 +2277,12 @@ extern void dhd_os_general_spin_unlock(dhd_pub_t *pub, unsigned long flags);
extern void dhd_dump_to_kernelog(dhd_pub_t *dhdp);
#ifdef BCMDBUS
extern uint dhd_get_rxsz(dhd_pub_t *pub);
extern void dhd_set_path(dhd_pub_t *pub);
extern void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
extern void dhd_bus_clearcounts(dhd_pub_t *dhdp);
#endif /* BCMDBUS */
#ifdef DHD_L2_FILTER
extern int dhd_get_parp_status(dhd_pub_t *dhdp, uint32 idx);

View File

@ -33,6 +33,10 @@
#ifndef _dhd_bus_h_
#define _dhd_bus_h_
extern int dbus_up(struct dhd_bus *pub);
extern int dbus_stop(struct dhd_bus *pub);
extern int dbus_send_ctl(struct dhd_bus *pub, uint8 *buf, int len);
extern int dbus_recv_ctl(struct dhd_bus *pub, uint8 *buf, int len);
/*
* Exported from dhd bus module (dhd_usb, dhd_sdio)
*/

View File

@ -49,6 +49,9 @@
#include <wlfc_proto.h>
#include <dhd_wlfc.h>
#endif
#ifdef BCMDBUS
#include <dhd_config.h>
#endif /* BCMDBUS */
#ifdef DHD_ULP
#include <dhd_ulp.h>
@ -68,15 +71,20 @@ typedef struct dhd_prot {
uint16 reqid;
uint8 pending;
uint32 lastcmd;
#ifdef BCMDBUS
uint ctl_completed;
#endif /* BCMDBUS */
uint8 bus_header[BUS_HEADER_LEN];
cdc_ioctl_t msg;
unsigned char buf[WLC_IOCTL_MAXLEN + ROUND_UP_MARGIN];
} dhd_prot_t;
static int
dhdcdc_msg(dhd_pub_t *dhd)
{
#ifdef BCMDBUS
int timeout = 0;
#endif /* BCMDBUS */
int err = 0;
dhd_prot_t *prot = dhd->prot;
int len = ltoh32(prot->msg.len) + sizeof(cdc_ioctl_t);
@ -93,8 +101,51 @@ dhdcdc_msg(dhd_pub_t *dhd)
len = CDC_MAX_MSG_SIZE;
/* Send request */
#ifdef BCMDBUS
DHD_OS_IOCTL_RESP_LOCK(dhd);
prot->ctl_completed = FALSE;
err = dbus_send_ctl(dhd->bus, (void *)&prot->msg, len);
if (err) {
DHD_ERROR(("dbus_send_ctl error=%d\n", err));
DHD_OS_IOCTL_RESP_UNLOCK(dhd);
DHD_OS_WAKE_UNLOCK(dhd);
return err;
}
#else
err = dhd_bus_txctl(dhd->bus, (uchar*)&prot->msg, len);
#endif /* BCMDBUS */
#ifdef BCMDBUS
timeout = dhd_os_ioctl_resp_wait(dhd, &prot->ctl_completed, false);
if ((!timeout) || (!prot->ctl_completed)) {
DHD_ERROR(("Txctl timeout %d ctl_completed %d\n",
timeout, prot->ctl_completed));
DHD_ERROR(("Txctl wait timed out\n"));
err = -1;
}
DHD_OS_IOCTL_RESP_UNLOCK(dhd);
#endif /* BCMDBUS */
#if defined(BCMDBUS) && defined(INTR_EP_ENABLE)
/* If the ctl write is successfully completed, wait for an acknowledgement
* that indicates that it is now ok to do ctl read from the dongle
*/
if (err != -1) {
DHD_OS_IOCTL_RESP_LOCK(dhd);
prot->ctl_completed = FALSE;
if (dbus_poll_intr(dhd->dbus)) {
DHD_ERROR(("dbus_poll_intr not submitted\n"));
} else {
/* interrupt polling is sucessfully submitted. Wait for dongle to send
* interrupt
*/
timeout = dhd_os_ioctl_resp_wait(dhd, &prot->ctl_completed, false);
if (!timeout) {
DHD_ERROR(("intr poll wait timed out\n"));
}
}
DHD_OS_IOCTL_RESP_UNLOCK(dhd);
}
#endif /* defined(BCMDBUS) && defined(INTR_EP_ENABLE) */
DHD_OS_WAKE_UNLOCK(dhd);
return err;
}
@ -102,6 +153,9 @@ dhdcdc_msg(dhd_pub_t *dhd)
static int
dhdcdc_cmplt(dhd_pub_t *dhd, uint32 id, uint32 len)
{
#ifdef BCMDBUS
int timeout = 0;
#endif /* BCMDBUS */
int ret;
int cdc_len = len + sizeof(cdc_ioctl_t);
dhd_prot_t *prot = dhd->prot;
@ -109,11 +163,37 @@ dhdcdc_cmplt(dhd_pub_t *dhd, uint32 id, uint32 len)
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
do {
#ifdef BCMDBUS
DHD_OS_IOCTL_RESP_LOCK(dhd);
prot->ctl_completed = FALSE;
ret = dbus_recv_ctl(dhd->bus, (uchar*)&prot->msg, cdc_len);
if (ret) {
DHD_ERROR(("dbus_recv_ctl error=0x%x(%d)\n", ret, ret));
DHD_OS_IOCTL_RESP_UNLOCK(dhd);
goto done;
}
timeout = dhd_os_ioctl_resp_wait(dhd, &prot->ctl_completed, false);
if ((!timeout) || (!prot->ctl_completed)) {
DHD_ERROR(("Rxctl timeout %d ctl_completed %d\n",
timeout, prot->ctl_completed));
ret = -1;
DHD_OS_IOCTL_RESP_UNLOCK(dhd);
goto done;
}
DHD_OS_IOCTL_RESP_UNLOCK(dhd);
ret = cdc_len;
#else
ret = dhd_bus_rxctl(dhd->bus, (uchar*)&prot->msg, cdc_len);
#endif /* BCMDBUS */
if (ret < 0)
break;
} while (CDC_IOC_ID(ltoh32(prot->msg.flags)) != id);
#ifdef BCMDBUS
done:
#endif /* BCMDBUS */
return ret;
}
@ -286,6 +366,25 @@ dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8
return ret;
}
#ifdef BCMDBUS
int
dhd_prot_ctl_complete(dhd_pub_t *dhd)
{
dhd_prot_t *prot;
if (dhd == NULL)
return BCME_ERROR;
prot = dhd->prot;
ASSERT(prot);
DHD_OS_IOCTL_RESP_LOCK(dhd);
prot->ctl_completed = TRUE;
dhd_os_ioctl_resp_wake(dhd);
DHD_OS_IOCTL_RESP_UNLOCK(dhd);
return 0;
}
#endif /* BCMDBUS */
int
dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len)
@ -487,6 +586,12 @@ dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, void *pktbuf, uchar *reorder_buf_in
dhd_wlfc_parse_header_info(dhd, pktbuf, (data_offset << 2),
reorder_buf_info, reorder_info_len);
#ifdef BCMDBUS
#ifndef DHD_WLFC_THREAD
dhd_wlfc_commit_packets(dhd,
(f_commitpkt_t)dhd_bus_txdata, dhd->bus, NULL, FALSE);
#endif /* DHD_WLFC_THREAD */
#endif /* BCMDBUS */
}
#endif /* PROP_TXSTATUS */
@ -572,6 +677,14 @@ dhd_sync_with_dongle(dhd_pub_t *dhd)
ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_REVINFO, &revinfo, sizeof(revinfo), FALSE, 0);
if (ret < 0)
goto done;
#if defined(BCMDBUS)
if (dhd_download_fw_on_driverload) {
dhd_conf_reset(dhd);
dhd_conf_set_chiprev(dhd, revinfo.chipnum, revinfo.chiprev);
dhd_conf_preinit(dhd);
dhd_conf_read_config(dhd, dhd->conf_path);
}
#endif /* BCMDBUS */
DHD_SSSR_DUMP_INIT(dhd);

View File

@ -161,8 +161,10 @@ void dhd_netdev_free(struct net_device *ndev)
#ifdef WL_CFG80211
ndev = dhd_cfg80211_netdev_free(ndev);
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
if (ndev)
free_netdev(ndev);
#endif
}
static s32

View File

@ -650,7 +650,11 @@ void* dhd_get_fwdump_buf(dhd_pub_t *dhd_pub, uint32 length)
int
dhd_common_socram_dump(dhd_pub_t *dhdp)
{
#ifdef BCMDBUS
return 0;
#else
return dhd_socram_dump(dhdp->bus);
#endif /* BCMDBUS */
}
static int
@ -1038,7 +1042,7 @@ dhd_iovar_parse_bssidx(dhd_pub_t *dhd_pub, const char *params, uint32 *idx, cons
return BCME_OK;
}
#if defined(DHD_DEBUG) && defined(BCMDHDUSB)
#if defined(DHD_DEBUG) && defined(BCMDBUS)
/* USB Device console input function */
int dhd_bus_console_in(dhd_pub_t *dhd, uchar *msg, uint msglen)
{
@ -1047,7 +1051,7 @@ int dhd_bus_console_in(dhd_pub_t *dhd, uchar *msg, uint msglen)
return dhd_iovar(dhd, 0, "cons", msg, msglen, NULL, 0, TRUE);
}
#endif /* DHD_DEBUG && BCMDHDUSB */
#endif /* DHD_DEBUG && BCMDBUS */
#ifdef DHD_DEBUG
int
@ -1263,10 +1267,12 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch
bcopy(&int_val, arg, val_size);
break;
#ifndef BCMDBUS
case IOV_GVAL(IOV_WDTICK):
int_val = (int32)dhd_watchdog_ms;
bcopy(&int_val, arg, val_size);
break;
#endif /* !BCMDBUS */
case IOV_SVAL(IOV_WDTICK):
if (!dhd_pub->up) {
@ -1285,6 +1291,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch
bcmerror = dhd_dump(dhd_pub, arg, len);
break;
#ifndef BCMDBUS
case IOV_GVAL(IOV_DCONSOLE_POLL):
int_val = (int32)dhd_console_ms;
bcopy(&int_val, arg, val_size);
@ -1298,6 +1305,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch
if (len > 0)
bcmerror = dhd_bus_console_in(dhd_pub, arg, len - 1);
break;
#endif /* !BCMDBUS */
case IOV_SVAL(IOV_CLEARCOUNTS):
dhd_pub->tx_packets = dhd_pub->rx_packets = 0;
@ -1423,9 +1431,9 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch
case IOV_GVAL(IOV_BUS_TYPE):
/* The dhd application queries the driver to check if its usb or sdio. */
#ifdef BCMDHDUSB
#ifdef BCMDBUS
int_val = BUS_TYPE_USB;
#endif
#endif /* BCMDBUS */
#ifdef BCMSDIO
int_val = BUS_TYPE_SDIO;
#endif
@ -1952,6 +1960,8 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch
break;
}
#endif /* REPORT_FATAL_TIMEOUTS */
#ifdef DHD_DEBUG
#if defined(BCMSDIO) || defined(BCMPCIE)
case IOV_GVAL(IOV_DONGLE_TRAP_TYPE):
if (dhd_pub->dongle_trap_occured)
int_val = ltoh32(dhd_pub->last_trap_info.type);
@ -1971,8 +1981,6 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch
dhd_bus_dump_trap_info(dhd_pub->bus, &strbuf);
break;
}
#ifdef DHD_DEBUG
#if defined(BCMSDIO) || defined(BCMPCIE)
case IOV_GVAL(IOV_BPADDR):
{
@ -2820,12 +2828,14 @@ dngl_host_event_process(dhd_pub_t *dhdp, bcm_dngl_event_t *event,
#ifdef DHD_FW_COREDUMP
dhdp->memdump_type = DUMP_TYPE_DONGLE_HOST_EVENT;
#endif /* DHD_FW_COREDUMP */
#ifndef BCMDBUS
if (dhd_socram_dump(dhdp->bus)) {
DHD_ERROR(("%s: socram dump failed\n", __FUNCTION__));
} else {
/* Notify framework */
dhd_dbg_send_urgent_evt(dhdp, p, datalen);
}
#endif /* !BCMDBUS */
}
#endif /* DNGL_EVENT_SUPPORT */
@ -3113,6 +3123,7 @@ wl_process_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, uint pktlen
dhd_ifname2idx(dhd_pub->info, event->ifname),
&event->addr.octet);
break;
#ifndef BCMDBUS
#if defined(DHD_FW_COREDUMP)
case WLC_E_PSM_WATCHDOG:
DHD_ERROR(("%s: WLC_E_PSM_WATCHDOG event received : \n", __FUNCTION__));
@ -3121,6 +3132,7 @@ wl_process_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, uint pktlen
}
break;
#endif
#endif /* !BCMDBUS */
#ifdef DHD_WMF
case WLC_E_PSTA_PRIMARY_INTF_IND:
dhd_update_psta_interface_for_sta(dhd_pub, event->ifname,
@ -3187,6 +3199,14 @@ wl_process_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, uint pktlen
default:
*ifidx = dhd_ifname2idx(dhd_pub->info, event->ifname);
#ifdef DHD_UPDATE_INTF_MAC
if ((WLC_E_LINK==type)&&(WLC_EVENT_MSG_LINK&flags)) {
dhd_event_ifchange(dhd_pub->info,
(struct wl_event_data_if *)event,
event->ifname,
event->addr.octet);
}
#endif /* DHD_UPDATE_INTF_MAC */
/* push up to external supp/auth */
dhd_event(dhd_pub->info, (char *)pvt_data, evlen, *ifidx);
DHD_TRACE(("%s: MAC event %d, flags %x, status %x\n",
@ -3580,7 +3600,7 @@ dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg)
htod16(WL_PKT_FILTER_MFLAG_NEG);
(argv[i])++;
}
if (strlen(argv[i]) == 0) {
if (*argv[i] == '\0') {
printf("Pattern not provided\n");
goto fail;
}
@ -4271,6 +4291,8 @@ dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd)
}
}
if (dhd->conf->suspend_bcn_li_dtim >= 0)
bcn_li_dtim = dhd->conf->suspend_bcn_li_dtim;
DHD_ERROR(("%s beacon=%d bcn_li_dtim=%d DTIM=%d Listen=%d\n",
__FUNCTION__, ap_beacon, bcn_li_dtim, dtim_period, CUSTOM_LISTEN_INTERVAL));
@ -4865,7 +4887,7 @@ dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path)
char iovbuf[WLC_IOCTL_SMLEN] = {0};
int status = FALSE;
if (clm_path[0] != '\0') {
if (clm_path && clm_path[0] != '\0') {
if (strlen(clm_path) > MOD_PARAM_PATHLEN) {
DHD_ERROR(("clm path exceeds max len\n"));
return BCME_ERROR;

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _dhd_config_
#define _dhd_config_
@ -9,36 +8,27 @@
#include <wlioctl.h>
#include <802.11.h>
#define FW_TYPE_STA 0
#define FW_TYPE_APSTA 1
#define FW_TYPE_P2P 2
#define FW_TYPE_MESH 3
#define FW_TYPE_ES 4
#define FW_TYPE_MFG 5
#define FW_TYPE_G 0
#define FW_TYPE_AG 1
#define FW_PATH_AUTO_SELECT 1
//#define CONFIG_PATH_AUTO_SELECT
extern char firmware_path[MOD_PARAM_PATHLEN];
#if defined(BCMSDIO) || defined(BCMPCIE)
extern uint dhd_rxbound;
extern uint dhd_txbound;
#endif
#ifdef BCMSDIO
#define TXGLOM_RECV_OFFSET 8
extern uint dhd_doflow;
extern uint dhd_slpauto;
#define BCM43362A0_CHIP_REV 0
#define BCM43362A2_CHIP_REV 1
#define BCM43430A0_CHIP_REV 0
#define BCM43430A1_CHIP_REV 1
#define BCM43430A2_CHIP_REV 2
#define BCM43012B0_CHIP_REV 1
#define BCM4330B2_CHIP_REV 4
#define BCM4334B1_CHIP_REV 3
#define BCM43341B0_CHIP_REV 2
#define BCM43241B4_CHIP_REV 5
#define BCM4335A0_CHIP_REV 2
#define BCM4339A0_CHIP_REV 1
#define BCM43455C0_CHIP_REV 6
#define BCM43456C5_CHIP_REV 9
#define BCM4354A1_CHIP_REV 1
#define BCM4359B1_CHIP_REV 5
#define BCM4359C0_CHIP_REV 9
#endif
#define BCM4356A2_CHIP_REV 2
#define BCM4358A3_CHIP_REV 3
typedef struct wl_mac_range {
uint32 oui;
@ -98,25 +88,35 @@ typedef struct conf_pkt_filter_del {
#define CONFIG_COUNTRY_LIST_SIZE 100
typedef struct conf_country_list {
uint32 count;
wl_country_t cspec[CONFIG_COUNTRY_LIST_SIZE];
wl_country_t *cspec[CONFIG_COUNTRY_LIST_SIZE];
} conf_country_list_t;
/* mchan_params */
#define MCHAN_MAX_NUM 4
#define MIRACAST_SOURCE 1
#define MIRACAST_SINK 2
typedef struct mchan_params {
int bw;
int p2p_mode;
int miracast_mode;
} mchan_params_t;
typedef struct dhd_conf {
uint chip;
uint chiprev;
int fw_type;
wl_mac_list_ctrl_t fw_by_mac;
wl_mac_list_ctrl_t nv_by_mac;
wl_chip_nv_path_list_ctrl_t nv_by_chip;
conf_country_list_t country_list;
conf_country_list_t country_list_nodfs;
int band;
int mimo_bw_cap;
int bw_cap_2g;
int bw_cap_5g;
int bw_cap[2];
wl_country_t cspec;
wl_channel_list_t channels;
uint roam_off;
uint roam_off_suspend;
int roam_trigger[2];
int roam_trigger[2];
int roam_scan_period[2];
int roam_delta[2];
int fullroamperiod;
@ -124,7 +124,6 @@ typedef struct dhd_conf {
int force_wme_ac;
wme_param_t wme_sta;
wme_param_t wme_ap;
int stbc;
int phy_oclscdenable;
#ifdef PKT_FILTER_SUPPORT
conf_pkt_filter_add_t pkt_filter_add;
@ -134,12 +133,10 @@ typedef struct dhd_conf {
int srl;
int lrl;
uint bcn_timeout;
int spect;
int txbf;
int lpc;
int disable_proptx;
int dhd_poll;
#ifdef BCMSDIO
int bus_txglom;
int use_rxchain;
bool bus_rxglom;
bool txglom_ext; /* Only for 43362/4330/43340/43341/43241 */
@ -150,7 +147,6 @@ typedef struct dhd_conf {
*/
int tx_max_offset;
uint txglomsize;
int dhd_poll;
int txctl_tmo_fix;
bool tx_in_rx;
bool txglom_mode;
@ -164,22 +160,22 @@ typedef struct dhd_conf {
int dhd_txminmax; // -1=DATABUFCNT(bus)
uint sd_f2_blocksize;
bool oob_enabled_later;
int orphan_move;
#endif
#ifdef BCMPCIE
int bus_deepsleep_disable;
#endif
int ampdu_ba_wsize;
int ampdu_hostreorder;
int dpc_cpucore;
int rxf_cpucore;
int frameburst;
bool deepsleep;
int pm;
int pm_in_suspend;
int pm2_sleep_ret;
int suspend_bcn_li_dtim;
#ifdef DHDTCPACK_SUPPRESS
uint8 tcpack_sup_mode;
#endif
int pktprio8021x;
int rsdb_mode;
int vhtmode;
int num_different_channels;
int xmit_in_suspend;
int ap_in_suspend;
@ -196,12 +192,15 @@ typedef struct dhd_conf {
struct ipv4_addr dhcpd_ip_start;
struct ipv4_addr dhcpd_ip_end;
#endif
#ifdef IAPSTA_PREINIT
char iapsta_init[50];
char iapsta_config[300];
char iapsta_enable[50];
#ifdef ISAM_PREINIT
char isam_init[50];
char isam_config[300];
char isam_enable[50];
#endif
int autocountry;
int ctrl_resched;
int dhd_ioctl_timeout_msec;
struct mchan_params mchan[MCHAN_MAX_NUM];
char *wl_preinit;
int tsq;
} dhd_conf_t;
@ -215,7 +214,7 @@ void dhd_conf_set_hw_oob_intr(bcmsdh_info_t *sdh, uint chip);
void dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable);
int dhd_conf_set_blksize(bcmsdh_info_t *sdh);
#endif
void dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path, char *nv_path);
void dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path);
void dhd_conf_set_clm_name_by_chip(dhd_pub_t *dhd, char *clm_path);
void dhd_conf_set_nv_name_by_chip(dhd_pub_t *dhd, char *nv_path);
void dhd_conf_set_path(dhd_pub_t *dhd, char *dst_name, char *dst_path, char *src_path);
@ -226,14 +225,13 @@ int dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val, int def
int dhd_conf_get_iovar(dhd_pub_t *dhd, int cmd, char *name, char *buf, int len, int ifidx);
int dhd_conf_set_bufiovar(dhd_pub_t *dhd, uint cmd, char *name, char *buf, int len, bool down);
uint dhd_conf_get_band(dhd_pub_t *dhd);
int dhd_conf_set_country(dhd_pub_t *dhd);
int dhd_conf_set_country(dhd_pub_t *dhd, wl_country_t *cspec);
int dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec);
int dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec);
int dhd_conf_map_country_list(dhd_pub_t *dhd, wl_country_t *cspec, int nodfs);
int dhd_conf_fix_country(dhd_pub_t *dhd);
bool dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel);
int dhd_conf_set_roam(dhd_pub_t *dhd);
void dhd_conf_set_bw_cap(dhd_pub_t *dhd);
void dhd_conf_set_wme(dhd_pub_t *dhd, int mode);
void dhd_conf_set_mchan_bw(dhd_pub_t *dhd, int go, int source);
void dhd_conf_add_pkt_filter(dhd_pub_t *dhd);
bool dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id);
void dhd_conf_discard_pkt_filter(dhd_pub_t *dhd);
@ -247,6 +245,7 @@ int dhd_conf_get_disable_proptx(dhd_pub_t *dhd);
#endif
int dhd_conf_get_ap_mode_in_suspend(dhd_pub_t *dhd);
int dhd_conf_set_ap_in_suspend(dhd_pub_t *dhd, int suspend);
void dhd_conf_postinit_ioctls(dhd_pub_t *dhd);
int dhd_conf_preinit(dhd_pub_t *dhd);
int dhd_conf_reset(dhd_pub_t *dhd);
int dhd_conf_attach(dhd_pub_t *dhd);

View File

@ -1,5 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <osl.h>
#include <dhd_linux.h>
#include <linux/gpio.h>
@ -148,10 +147,10 @@ static int dhd_wlan_get_mac_addr(unsigned char *buf)
bcopy((char *)&ea_example, buf, sizeof(struct ether_addr));
}
#endif /* EXAMPLE_GET_MAC */
err = rockchip_wifi_mac_addr(buf);
#ifdef EXAMPLE_GET_MAC_VER2
/* EXAMPLE code */
{
char mac[6] = {0x00,0x11,0x22,0x33,0x44,0xFF};
char macpad[56]= {
0x00,0xaa,0x9c,0x84,0xc7,0xbc,0x9b,0xf6,
0x02,0x33,0xa9,0x4d,0x5c,0xb4,0x0a,0x5d,
@ -160,11 +159,9 @@ static int dhd_wlan_get_mac_addr(unsigned char *buf)
0x4a,0xeb,0xf6,0xe6,0x3c,0xe7,0x5f,0xfc,
0x0e,0xa7,0xb3,0x0f,0x00,0xe4,0x4a,0xaf,
0x87,0x08,0x16,0x6d,0x3a,0xe3,0xc7,0x80};
bcopy(mac, buf, sizeof(mac));
bcopy(macpad, buf+6, sizeof(macpad));
}
#endif /* EXAMPLE_GET_MAC_VER2 */
err = rockchip_wifi_mac_addr(buf);
return err;
}
@ -244,7 +241,6 @@ int dhd_wlan_init_gpio(void)
#ifdef CUSTOMER_OOB
int host_oob_irq = -1;
uint host_oob_irq_flags = 0;
int irq_flags = -1;
#endif
/* Please check your schematic and fill right GPIO number which connected to
@ -255,56 +251,54 @@ int dhd_wlan_init_gpio(void)
gpio_wl_host_wake = -1;
#endif
printf("%s: GPIO(WL_REG_ON) = %d\n", __FUNCTION__, gpio_wl_reg_on);
if (gpio_wl_reg_on >= 0) {
err = gpio_request(gpio_wl_reg_on, "WL_REG_ON");
if (err < 0) {
printf("%s: Faiiled to request gpio %d for WL_REG_ON\n",
printf("%s: gpio_request(%d) for WL_REG_ON failed\n",
__FUNCTION__, gpio_wl_reg_on);
gpio_wl_reg_on = -1;
}
}
#ifdef CUSTOMER_OOB
printf("%s: GPIO(WL_HOST_WAKE) = %d\n", __FUNCTION__, gpio_wl_host_wake);
if (gpio_wl_host_wake >= 0) {
err = gpio_request(gpio_wl_host_wake, "bcmdhd");
if (err < 0) {
printf("%s: gpio_request failed\n", __FUNCTION__);
printf("%s: gpio_request(%d) for WL_HOST_WAKE failed\n",
__FUNCTION__, gpio_wl_host_wake);
return -1;
}
err = gpio_direction_input(gpio_wl_host_wake);
if (err < 0) {
printf("%s: gpio_direction_input failed\n", __FUNCTION__);
printf("%s: gpio_direction_input(%d) for WL_HOST_WAKE failed\n",
__FUNCTION__, gpio_wl_host_wake);
gpio_free(gpio_wl_host_wake);
return -1;
}
host_oob_irq = gpio_to_irq(gpio_wl_host_wake);
if (host_oob_irq < 0) {
printf("%s: gpio_to_irq failed\n", __FUNCTION__);
printf("%s: gpio_to_irq(%d) for WL_HOST_WAKE failed\n",
__FUNCTION__, gpio_wl_host_wake);
gpio_free(gpio_wl_host_wake);
return -1;
}
}
host_oob_irq = rockchip_wifi_get_oob_irq();
printf("%s: host_oob_irq: %d\n", __FUNCTION__, host_oob_irq);
#ifdef HW_OOB
host_oob_irq_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE;
irq_flags = rockchip_wifi_get_oob_irq_flag();
if (irq_flags == 1)
host_oob_irq_flags |= IORESOURCE_IRQ_HIGHLEVEL;
else if (irq_flags == 0)
host_oob_irq_flags |= IORESOURCE_IRQ_LOWLEVEL;
else
pr_warn("%s: unknown oob irqflags !\n", __func__);
#ifdef HW_OOB_LOW_LEVEL
host_oob_irq_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL | IORESOURCE_IRQ_SHAREABLE;
#else
host_oob_irq_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE;
#endif
#else
host_oob_irq_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_SHAREABLE;
#endif
dhd_wlan_resources[0].start = dhd_wlan_resources[0].end = host_oob_irq;
dhd_wlan_resources[0].flags = host_oob_irq_flags;
printf("%s: host_oob_irq_flags=0x%x\n", __FUNCTION__, host_oob_irq_flags);
printf("%s: WL_REG_ON=%d, WL_HOST_WAKE=%d\n", __FUNCTION__, gpio_wl_reg_on, gpio_wl_host_wake);
printf("%s: oob_irq=%d, oob_irq_flags=0x%x\n", __FUNCTION__, host_oob_irq, host_oob_irq_flags);
#endif /* CUSTOMER_OOB */
return 0;

View File

@ -287,10 +287,20 @@ static void _tdata_psh_info_pool_deinit(dhd_pub_t *dhdp,
return;
}
static void dhd_tcpack_send(ulong data)
static void dhd_tcpack_send(
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
struct timer_list *t
#else
ulong data
#endif
)
{
tcpack_sup_module_t *tcpack_sup_mod;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
tcpack_info_t *cur_tbl = from_timer(cur_tbl, t, timer);
#else
tcpack_info_t *cur_tbl = (tcpack_info_t *)data;
#endif
dhd_pub_t *dhdp;
int ifidx;
void* pkt;
@ -464,9 +474,13 @@ int dhd_tcpack_suppress_set(dhd_pub_t *dhdp, uint8 mode)
tcpack_info_t *tcpack_info_tbl =
&tcpack_sup_module->tcpack_info_tbl[i];
tcpack_info_tbl->dhdp = dhdp;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
timer_setup(&tcpack_info_tbl->timer, dhd_tcpack_send, 0);
#else
init_timer(&tcpack_info_tbl->timer);
tcpack_info_tbl->timer.data = (ulong)tcpack_info_tbl;
tcpack_info_tbl->timer.function = dhd_tcpack_send;
#endif
}
break;
}

File diff suppressed because it is too large Load Diff

View File

@ -51,7 +51,21 @@
#include <linux/earlysuspend.h>
#endif /* defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) */
/* dongle status */
enum wifi_adapter_status {
WIFI_STATUS_POWER_ON = 0,
WIFI_STATUS_ATTACH,
WIFI_STATUS_FW_READY,
WIFI_STATUS_DETTACH
};
#define wifi_chk_adapter_status(adapter, stat) (test_bit(stat, &(adapter)->status))
#define wifi_get_adapter_status(adapter, stat) (test_bit(stat, &(adapter)->status))
#define wifi_set_adapter_status(adapter, stat) (set_bit(stat, &(adapter)->status))
#define wifi_clr_adapter_status(adapter, stat) (clear_bit(stat, &(adapter)->status))
#define wifi_chg_adapter_status(adapter, stat) (change_bit(stat, &(adapter)->status))
#define DHD_REGISTRATION_TIMEOUT 12000 /* msec : allowed time to finished dhd registration */
#define DHD_FW_READY_TIMEOUT 5000 /* msec : allowed time to finished fw download */
typedef struct wifi_adapter_info {
const char *name;
@ -65,6 +79,8 @@ typedef struct wifi_adapter_info {
uint bus_type;
uint bus_num;
uint slot_num;
wait_queue_head_t status_event;
unsigned long status;
#if defined(BT_OVER_SDIO)
const char *btfw_path;
#endif /* defined (BT_OVER_SDIO) */
@ -120,6 +136,8 @@ typedef dhd_sta_t dhd_sta_pool_t;
int dhd_wifi_platform_register_drv(void);
void dhd_wifi_platform_unregister_drv(void);
wifi_adapter_info_t* dhd_wifi_platform_attach_adapter(uint32 bus_type,
uint32 bus_num, uint32 slot_num, unsigned long status);
wifi_adapter_info_t* dhd_wifi_platform_get_adapter(uint32 bus_type, uint32 bus_num,
uint32 slot_num);
int wifi_platform_set_power(wifi_adapter_info_t *adapter, bool on, unsigned long msec);

View File

@ -58,6 +58,7 @@ extern void dhd_wlan_deinit_plat_data(wifi_adapter_info_t *adapter);
#ifdef CONFIG_DTS
struct regulator *wifi_regulator = NULL;
extern struct wifi_platform_data dhd_wlan_control;
#endif /* CONFIG_DTS */
bool cfg_multichip = FALSE;
@ -93,6 +94,30 @@ extern void bcm_bt_unlock(int cookie);
static int lock_cookie_wifi = 'W' | 'i'<<8 | 'F'<<16 | 'i'<<24; /* cookie is "WiFi" */
#endif /* ENABLE_4335BT_WAR */
wifi_adapter_info_t* dhd_wifi_platform_attach_adapter(uint32 bus_type,
uint32 bus_num, uint32 slot_num, unsigned long status)
{
int i;
if (dhd_wifi_platdata == NULL)
return NULL;
for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
wifi_adapter_info_t *adapter = &dhd_wifi_platdata->adapters[i];
if ((adapter->bus_type == -1 || adapter->bus_type == bus_type) &&
(adapter->bus_num == -1 || adapter->bus_num == bus_num) &&
(adapter->slot_num == -1 || adapter->slot_num == slot_num)
#if defined(ENABLE_INSMOD_NO_FW_LOAD)
&& (wifi_chk_adapter_status(adapter, status))
#endif
) {
DHD_ERROR(("attach adapter info '%s'\n", adapter->name));
return adapter;
}
}
return NULL;
}
wifi_adapter_info_t* dhd_wifi_platform_get_adapter(uint32 bus_type, uint32 bus_num, uint32 slot_num)
{
int i;
@ -165,20 +190,31 @@ int wifi_platform_set_power(wifi_adapter_info_t *adapter, bool on, unsigned long
return -EINVAL;
}
#endif /* BT_OVER_SDIO */
if (on) {
wifi_set_adapter_status(adapter, WIFI_STATUS_POWER_ON);
} else {
wifi_clr_adapter_status(adapter, WIFI_STATUS_POWER_ON);
}
#ifdef CONFIG_DTS
if (on) {
printf("======== PULL WL_REG_ON HIGH! ========\n");
err = regulator_enable(wifi_regulator);
is_power_on = TRUE;
}
else {
printf("======== PULL WL_REG_ON LOW! ========\n");
err = regulator_disable(wifi_regulator);
is_power_on = FALSE;
}
if (err < 0)
if (err < 0) {
DHD_ERROR(("%s: regulator enable/disable failed", __FUNCTION__));
goto fail;
}
#else
if (!adapter || !adapter->wifi_plat_data)
return -EINVAL;
if (!adapter || !adapter->wifi_plat_data) {
err = -EINVAL;
goto fail;
}
plat_data = adapter->wifi_plat_data;
DHD_ERROR(("%s = %d\n", __FUNCTION__, on));
@ -213,6 +249,13 @@ int wifi_platform_set_power(wifi_adapter_info_t *adapter, bool on, unsigned long
#endif /* CONFIG_DTS */
return err;
fail:
if (on) {
wifi_clr_adapter_status(adapter, WIFI_STATUS_POWER_ON);
} else {
wifi_set_adapter_status(adapter, WIFI_STATUS_POWER_ON);
}
return err;
}
@ -280,7 +323,7 @@ static int wifi_plat_dev_drv_probe(struct platform_device *pdev)
{
struct resource *resource;
wifi_adapter_info_t *adapter;
#ifdef CONFIG_DTS
#if defined(CONFIG_DTS) && defined(CUSTOMER_OOB)
int irq, gpio;
#endif /* CONFIG_DTS */
@ -290,7 +333,8 @@ static int wifi_plat_dev_drv_probe(struct platform_device *pdev)
ASSERT(dhd_wifi_platdata != NULL);
ASSERT(dhd_wifi_platdata->num_adapters == 1);
adapter = &dhd_wifi_platdata->adapters[0];
adapter->wifi_plat_data = (struct wifi_platform_data *)(pdev->dev.platform_data);
adapter->wifi_plat_data = (void *)&dhd_wlan_control;
// adapter->wifi_plat_data = (struct wifi_platform_data *)(pdev->dev.platform_data);
resource = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcmdhd_wlan_irq");
if (resource == NULL)
@ -310,6 +354,7 @@ static int wifi_plat_dev_drv_probe(struct platform_device *pdev)
return -1;
}
#if defined(CUSTOMER_OOB)
/* This is to get the irq for the OOB */
gpio = of_get_gpio(pdev->dev.of_node, 0);
@ -327,6 +372,7 @@ static int wifi_plat_dev_drv_probe(struct platform_device *pdev)
/* need to change the flags according to our requirement */
adapter->intr_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL |
IORESOURCE_IRQ_SHAREABLE;
#endif
#endif /* CONFIG_DTS */
wifi_plat_dev_probe_ret = dhd_wifi_platform_load();
@ -469,6 +515,7 @@ static int wifi_ctrlfunc_register_drv(void)
dhd_wifi_platdata = kzalloc(sizeof(bcmdhd_wifi_platdata_t), GFP_KERNEL);
dhd_wifi_platdata->num_adapters = 1;
dhd_wifi_platdata->adapters = adapter;
init_waitqueue_head(&adapter->status_event);
#ifndef CUSTOMER_HW
if (dev1) {
@ -519,7 +566,9 @@ static int wifi_ctrlfunc_register_drv(void)
void wifi_ctrlfunc_unregister_drv(void)
{
#ifndef CONFIG_DTS
wifi_adapter_info_t *adapter;
#endif
#if defined(CONFIG_DTS) && !defined(CUSTOMER_HW)
DHD_ERROR(("unregister wifi platform drivers\n"));
@ -730,7 +779,7 @@ void dhd_wifi_platform_unregister_drv(void)
extern int dhd_watchdog_prio;
extern int dhd_dpc_prio;
extern uint dhd_deferred_tx;
#if defined(BCMLXSDMMC)
#if defined(BCMLXSDMMC) || defined(BCMDBUS)
extern struct semaphore dhd_registration_sem;
#endif
@ -854,10 +903,67 @@ static int dhd_wifi_platform_load_sdio(void)
}
#endif /* BCMSDIO */
#ifdef BCMDBUS
static int dhd_wifi_platform_load_usb(void)
{
wifi_adapter_info_t *adapter;
s32 timeout = -1;
int i;
int err = 0;
enum wifi_adapter_status wait_status;
err = dhd_bus_register();
if (err) {
DHD_ERROR(("%s: usb_register failed\n", __FUNCTION__));
goto exit;
}
/* power up all adapters */
for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
adapter = &dhd_wifi_platdata->adapters[i];
DHD_ERROR(("Power-up adapter '%s'\n", adapter->name));
DHD_INFO((" - irq %d [flags %d], firmware: %s, nvram: %s\n",
adapter->irq_num, adapter->intr_flags, adapter->fw_path, adapter->nv_path));
DHD_INFO((" - bus type %d, bus num %d, slot num %d\n\n",
adapter->bus_type, adapter->bus_num, adapter->slot_num));
err = wifi_platform_set_power(adapter, TRUE, WIFI_TURNON_DELAY);
if (err) {
DHD_ERROR(("failed to wifi_platform_set_power on %s\n", adapter->name));
goto fail;
}
if (dhd_download_fw_on_driverload)
wait_status = WIFI_STATUS_ATTACH;
else
wait_status = WIFI_STATUS_DETTACH;
timeout = wait_event_interruptible_timeout(adapter->status_event,
wifi_get_adapter_status(adapter, wait_status),
msecs_to_jiffies(DHD_REGISTRATION_TIMEOUT));
if (timeout <= 0) {
err = -1;
DHD_ERROR(("%s: usb_register_driver timeout\n", __FUNCTION__));
goto fail;
}
}
exit:
return err;
fail:
dhd_bus_unregister();
/* power down all adapters */
for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
adapter = &dhd_wifi_platdata->adapters[i];
wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
}
return err;
}
#else /* BCMDBUS */
static int dhd_wifi_platform_load_usb(void)
{
return 0;
}
#endif /* BCMDBUS */
static int dhd_wifi_platform_load()
{

View File

@ -47,6 +47,9 @@ enum _wq_event {
DHD_WQ_WORK_DEBUG_UART_DUMP,
DHD_WQ_WORK_SSSR_DUMP,
DHD_WQ_WORK_PKTLOG_DUMP,
#ifdef DHD_UPDATE_INTF_MAC
DHD_WQ_WORK_IF_UPDATE,
#endif /* DHD_UPDATE_INTF_MAC */
DHD_MAX_WQ_EVENTS
};

View File

@ -52,6 +52,7 @@
#include <pcie_core.h>
#include <bcmpcie.h>
#include <dhd_pcie.h>
#include <dhd_config.h>
#ifdef DHD_TIMESYNC
#include <dhd_timesync.h>
#endif /* DHD_TIMESYNC */
@ -6013,6 +6014,7 @@ dhd_msgbuf_wait_ioctl_cmplt(dhd_pub_t *dhd, uint32 len, void *buf)
int timeleft;
unsigned long flags;
int ret = 0;
static uint cnt = 0;
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
@ -6021,7 +6023,7 @@ dhd_msgbuf_wait_ioctl_cmplt(dhd_pub_t *dhd, uint32 len, void *buf)
goto out;
}
timeleft = dhd_os_ioctl_resp_wait(dhd, (uint *)&prot->ioctl_received);
timeleft = dhd_os_ioctl_resp_wait(dhd, (uint *)&prot->ioctl_received, false);
#ifdef DHD_RECOVER_TIMEOUT
if (prot->ioctl_received == 0) {
@ -6053,6 +6055,25 @@ dhd_msgbuf_wait_ioctl_cmplt(dhd_pub_t *dhd, uint32 len, void *buf)
}
#endif /* DHD_RECOVER_TIMEOUT */
if (dhd->conf->ctrl_resched > 0 && timeleft == 0 && (!dhd_query_bus_erros(dhd))) {
cnt++;
if (cnt <= dhd->conf->ctrl_resched) {
uint32 intstatus = 0, intmask = 0;
intstatus = si_corereg(dhd->bus->sih, dhd->bus->sih->buscoreidx, PCIMailBoxInt, 0, 0);
intmask = si_corereg(dhd->bus->sih, dhd->bus->sih->buscoreidx, PCIMailBoxMask, 0, 0);
if (intstatus) {
DHD_ERROR(("%s: reschedule dhd_dpc, cnt=%d, intstatus=0x%x, intmask=0x%x\n",
__FUNCTION__, cnt, intstatus, intmask));
dhd->bus->ipend = TRUE;
dhd->bus->dpc_sched = TRUE;
dhd_sched_dpc(dhd);
timeleft = dhd_os_ioctl_resp_wait(dhd, &prot->ioctl_received, true);
}
}
} else {
cnt = 0;
}
if (timeleft == 0 && (!dhd_query_bus_erros(dhd))) {
uint32 intstatus;

View File

@ -497,7 +497,9 @@ uint32
dhdpcie_bus_intstatus(dhd_bus_t *bus)
{
uint32 intstatus = 0;
#ifndef DHD_READ_INTSTATUS_IN_DPC
uint32 intmask = 0;
#endif /* DHD_READ_INTSTATUS_IN_DPC */
if ((bus->dhd->busstate == DHD_BUS_SUSPEND || bus->d3_suspend_pending) &&
bus->wait_for_d3_ack) {
@ -521,10 +523,12 @@ dhdpcie_bus_intstatus(dhd_bus_t *bus)
/* this is a PCIE core register..not a config register... */
intstatus = si_corereg(bus->sih, bus->sih->buscoreidx, PCIMailBoxInt, 0, 0);
#ifndef DHD_READ_INTSTATUS_IN_DPC
/* this is a PCIE core register..not a config register... */
intmask = si_corereg(bus->sih, bus->sih->buscoreidx, PCIMailBoxMask, 0, 0);
intstatus &= intmask;
#endif /* DHD_READ_INTSTATUS_IN_DPC */
/* Is device removed. intstatus & intmask read 0xffffffff */
if (intstatus == (uint32)-1) {
DHD_ERROR(("%s: Device is removed or Link is down.\n", __FUNCTION__));
@ -600,6 +604,7 @@ dhdpcie_bus_isr(dhd_bus_t *bus)
}
}
#ifndef DHD_READ_INTSTATUS_IN_DPC
intstatus = dhdpcie_bus_intstatus(bus);
/* Check if the interrupt is ours or not */
@ -627,6 +632,7 @@ dhdpcie_bus_isr(dhd_bus_t *bus)
/* Count the interrupt call */
bus->intrcount++;
#endif /* DHD_READ_INTSTATUS_IN_DPC */
bus->ipend = TRUE;
@ -988,6 +994,9 @@ dhdpcie_dongle_attach(dhd_bus_t *bus)
case BCM4347_CHIP_GRPID:
bus->dongle_ram_base = CR4_4347_RAM_BASE;
break;
case BCM4362_CHIP_ID:
bus->dongle_ram_base = CR4_4362_RAM_BASE;
break;
default:
bus->dongle_ram_base = 0;
DHD_ERROR(("%s: WARNING: Using default ram base at 0x%x\n",
@ -1008,6 +1017,8 @@ dhdpcie_dongle_attach(dhd_bus_t *bus)
/* Set the poll and/or interrupt flags */
bus->intr = (bool)dhd_intr;
if ((bus->poll = (bool)dhd_poll))
bus->pollrate = 1;
bus->wait_for_d3_ack = 1;
#ifdef PCIE_OOB
@ -1116,6 +1127,27 @@ dhdpcie_advertise_bus_cleanup(dhd_pub_t *dhdp)
return;
}
static void
dhdpcie_advertise_bus_remove(dhd_pub_t *dhdp)
{
unsigned long flags;
int timeleft;
DHD_GENERAL_LOCK(dhdp, flags);
dhdp->busstate = DHD_BUS_REMOVE;
DHD_GENERAL_UNLOCK(dhdp, flags);
timeleft = dhd_os_busbusy_wait_negation(dhdp, &dhdp->dhd_bus_busy_state);
if ((timeleft == 0) || (timeleft == 1)) {
DHD_ERROR(("%s : Timeout due to dhd_bus_busy_state=0x%x\n",
__FUNCTION__, dhdp->dhd_bus_busy_state));
ASSERT(0);
}
return;
}
static void
dhdpcie_bus_remove_prep(dhd_bus_t *bus)
{
@ -1169,7 +1201,7 @@ dhdpcie_bus_release(dhd_bus_t *bus)
ASSERT(osh);
if (bus->dhd) {
dhdpcie_advertise_bus_cleanup(bus->dhd);
dhdpcie_advertise_bus_remove(bus->dhd);
dongle_isolation = bus->dhd->dongle_isolation;
bus->dhd->is_pcie_watchdog_reset = FALSE;
dhdpcie_bus_remove_prep(bus);
@ -1509,6 +1541,14 @@ bool dhd_bus_watchdog(dhd_pub_t *dhd)
}
}
#ifdef DHD_READ_INTSTATUS_IN_DPC
if (bus->poll) {
bus->ipend = TRUE;
bus->dpc_sched = TRUE;
dhd_sched_dpc(bus->dhd); /* queue DPC now!! */
}
#endif /* DHD_READ_INTSTATUS_IN_DPC */
#if defined(PCIE_OOB) || defined(PCIE_INB_DW)
/* If haven't communicated with device for a while, deassert the Device_Wake GPIO */
if (dhd_doorbell_timeout != 0 && dhd->busstate == DHD_BUS_DATA &&
@ -1618,6 +1658,17 @@ dhd_set_path_params(struct dhd_bus *bus)
}
void
dhd_set_bus_params(struct dhd_bus *bus)
{
if (bus->dhd->conf->dhd_poll >= 0) {
bus->poll = bus->dhd->conf->dhd_poll;
if (!bus->pollrate)
bus->pollrate = 1;
printf("%s: set polling mode %d\n", __FUNCTION__, bus->dhd->conf->dhd_poll);
}
}
static int
dhdpcie_download_firmware(struct dhd_bus *bus, osl_t *osh)
{
@ -1659,6 +1710,7 @@ dhdpcie_download_firmware(struct dhd_bus *bus, osl_t *osh)
DHD_OS_WAKE_LOCK(bus->dhd);
dhd_set_path_params(bus);
dhd_set_bus_params(bus);
ret = _dhdpcie_download_firmware(bus);
@ -6045,10 +6097,24 @@ dhd_bus_dpc(struct dhd_bus *bus)
DHD_BUS_BUSY_SET_IN_DPC(bus->dhd);
DHD_GENERAL_UNLOCK(bus->dhd, flags);
#ifdef DHD_READ_INTSTATUS_IN_DPC
if (bus->ipend) {
bus->ipend = FALSE;
bus->intstatus = dhdpcie_bus_intstatus(bus);
/* Check if the interrupt is ours or not */
if (bus->intstatus == 0) {
goto INTR_ON;
}
bus->intrcount++;
}
#endif /* DHD_READ_INTSTATUS_IN_DPC */
resched = dhdpcie_bus_process_mailbox_intr(bus, bus->intstatus);
if (!resched) {
bus->intstatus = 0;
#ifdef DHD_READ_INTSTATUS_IN_DPC
INTR_ON:
#endif /* DHD_READ_INTSTATUS_IN_DPC */
bus->dpc_intr_enable_count++;
dhdpcie_bus_intr_enable(bus); /* Enable back interrupt using Intmask!! */
}
@ -7025,6 +7091,11 @@ dhdpcie_chipmatch(uint16 vendor, uint16 device)
if ((device == BCM4361_D11AC_ID) || (device == BCM4361_D11AC2G_ID) ||
(device == BCM4361_D11AC5G_ID) || (device == BCM4361_CHIP_ID))
return 0;
if ((device == BCM4362_D11AX_ID) || (device == BCM4362_D11AX2G_ID) ||
(device == BCM4362_D11AX5G_ID) || (device == BCM4362_CHIP_ID)) {
return 0;
}
if ((device == BCM4365_D11AC_ID) || (device == BCM4365_D11AC2G_ID) ||
(device == BCM4365_D11AC5G_ID) || (device == BCM4365_CHIP_ID))

View File

@ -259,6 +259,7 @@ typedef struct dhd_bus {
struct pktq txq; /* Queue length used for flow-control */
bool intr; /* Use interrupts */
bool poll; /* Use polling */
bool ipend; /* Device interrupt is pending */
bool intdis; /* Interrupts disabled by isr */
uint intrcount; /* Count of device interrupt callbacks */

View File

@ -178,12 +178,6 @@ static int dhdpcie_init(struct pci_dev *pdev);
static irqreturn_t dhdpcie_isr(int irq, void *arg);
/* OS Routine functions for PCI suspend/resume */
#if defined(MULTIPLE_SUPPLICANT)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
DEFINE_MUTEX(_dhd_sdio_mutex_lock_);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */
#endif
static int dhdpcie_set_suspend_resume(dhd_bus_t *bus, bool state);
static int dhdpcie_resume_host_dev(dhd_bus_t *bus);
static int dhdpcie_suspend_host_dev(dhd_bus_t *bus);
@ -890,9 +884,7 @@ dhdpcie_bus_unregister(void)
int __devinit
dhdpcie_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
#ifdef BUS_POWER_RESTORE
wifi_adapter_info_t *adapter = NULL;
#endif
DHD_MUTEX_LOCK();
if (dhdpcie_chipmatch (pdev->vendor, pdev->device)) {
DHD_ERROR(("%s: chipmatch failed!!\n", __FUNCTION__));
@ -912,15 +904,8 @@ dhdpcie_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
device_disable_async_suspend(&pdev->dev);
#endif /* BCMPCIE_DISABLE_ASYNC_SUSPEND */
#ifdef BUS_POWER_RESTORE
adapter = dhd_wifi_platform_get_adapter(PCI_BUS, pdev->bus->number,
PCI_SLOT(pdev->devfn));
if (adapter != NULL)
adapter->pci_dev = pdev;
#endif
DHD_TRACE(("%s: PCIe Enumeration done!!\n", __FUNCTION__));
DHD_MUTEX_UNLOCK();
return 0;
}
@ -948,17 +933,7 @@ dhdpcie_pci_remove(struct pci_dev *pdev)
DHD_TRACE(("%s Enter\n", __FUNCTION__));
#if defined(MULTIPLE_SUPPLICANT)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
if (mutex_is_locked(&_dhd_sdio_mutex_lock_) == 0) {
DHD_ERROR(("%s : no mutex held. set lock\n", __FUNCTION__));
}
else {
DHD_ERROR(("%s : mutex is locked!. wait for unlocking\n", __FUNCTION__));
}
mutex_lock(&_dhd_sdio_mutex_lock_);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */
#endif
DHD_MUTEX_LOCK();
pch = pci_get_drvdata(pdev);
bus = pch->bus;
@ -1006,12 +981,7 @@ dhdpcie_pci_remove(struct pci_dev *pdev)
dhdpcie_init_succeeded = FALSE;
#if defined(MULTIPLE_SUPPLICANT)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
mutex_unlock(&_dhd_sdio_mutex_lock_);
DHD_ERROR(("%s : the lock is released.\n", __FUNCTION__));
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */
#endif /* LINUX */
DHD_MUTEX_UNLOCK();
DHD_TRACE(("%s Exit\n", __FUNCTION__));
@ -1029,10 +999,22 @@ dhdpcie_request_irq(dhdpcie_info_t *dhdpcie_info)
if (!bus->irq_registered) {
snprintf(dhdpcie_info->pciname, sizeof(dhdpcie_info->pciname),
"dhdpcie:%s", pci_name(pdev));
#ifdef DHD_USE_MSI
printf("%s: MSI enabled\n", __FUNCTION__);
err = pci_enable_msi(pdev);
if (err < 0) {
DHD_ERROR(("%s: pci_enable_msi() failed, %d, fall back to INTx\n", __FUNCTION__, err));
}
#else
printf("%s: MSI not enabled\n", __FUNCTION__);
#endif /* DHD_USE_MSI */
err = request_irq(pdev->irq, dhdpcie_isr, IRQF_SHARED,
dhdpcie_info->pciname, bus);
if (err) {
DHD_ERROR(("%s: request_irq() failed\n", __FUNCTION__));
#ifdef DHD_USE_MSI
pci_disable_msi(pdev);
#endif /* DHD_USE_MSI */
return -1;
} else {
bus->irq_registered = TRUE;
@ -1226,10 +1208,6 @@ void dhdpcie_linkdown_cb(struct_pcie_notify *noti)
*/
#endif /* SUPPORT_LINKDOWN_RECOVERY */
#if defined(MULTIPLE_SUPPLICANT)
extern void wl_android_post_init(void); // terence 20120530: fix critical section in dhd_open and dhdsdio_probe
#endif
int dhdpcie_init(struct pci_dev *pdev)
{
@ -1244,18 +1222,6 @@ int dhdpcie_init(struct pci_dev *pdev)
dhdpcie_smmu_info_t *dhdpcie_smmu_info = NULL;
#endif /* USE_SMMU_ARCH_MSM */
#if defined(MULTIPLE_SUPPLICANT)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
if (mutex_is_locked(&_dhd_sdio_mutex_lock_) == 0) {
DHD_ERROR(("%s : no mutex held. set lock\n", __FUNCTION__));
}
else {
DHD_ERROR(("%s : mutex is locked!. wait for unlocking\n", __FUNCTION__));
}
mutex_lock(&_dhd_sdio_mutex_lock_);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */
#endif
do {
/* osl attach */
if (!(osh = osl_attach(pdev, PCI_BUS, FALSE))) {
@ -1266,9 +1232,12 @@ int dhdpcie_init(struct pci_dev *pdev)
/* initialize static buffer */
adapter = dhd_wifi_platform_get_adapter(PCI_BUS, pdev->bus->number,
PCI_SLOT(pdev->devfn));
if (adapter != NULL)
if (adapter != NULL) {
DHD_ERROR(("%s: found adapter info '%s'\n", __FUNCTION__, adapter->name));
else
#ifdef BUS_POWER_RESTORE
adapter->pci_dev = pdev;
#endif
} else
DHD_ERROR(("%s: can't find adapter info for this chip\n", __FUNCTION__));
osl_static_mem_init(osh, adapter);
@ -1438,11 +1407,7 @@ int dhdpcie_init(struct pci_dev *pdev)
#if defined(MULTIPLE_SUPPLICANT)
wl_android_post_init(); // terence 20120530: fix critical section in dhd_open and dhdsdio_probe
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
mutex_unlock(&_dhd_sdio_mutex_lock_);
DHD_ERROR(("%s : the lock is released.\n", __FUNCTION__));
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
#endif
#endif /* MULTIPLE_SUPPLICANT */
DHD_TRACE(("%s:Exit - SUCCESS \n", __FUNCTION__));
return 0; /* return SUCCESS */
@ -1473,12 +1438,6 @@ int dhdpcie_init(struct pci_dev *pdev)
osl_detach(osh);
dhdpcie_init_succeeded = FALSE;
#if defined(MULTIPLE_SUPPLICANT)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
mutex_unlock(&_dhd_sdio_mutex_lock_);
DHD_ERROR(("%s : the lock is released.\n", __FUNCTION__));
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
#endif
DHD_TRACE(("%s:Exit - FAILURE \n", __FUNCTION__));
@ -1497,6 +1456,9 @@ dhdpcie_free_irq(dhd_bus_t *bus)
if (bus->irq_registered) {
free_irq(pdev->irq, bus);
bus->irq_registered = FALSE;
#ifdef DHD_USE_MSI
pci_disable_msi(pdev);
#endif /* DHD_USE_MSI */
} else {
DHD_ERROR(("%s: PCIe IRQ is not registered\n", __FUNCTION__));
}
@ -2296,6 +2258,7 @@ bool dhdpcie_is_resume_done(dhd_pub_t *dhdp)
return bus->runtime_resume_done;
}
#endif /* DHD_PCIE_RUNTIMEPM */
struct device * dhd_bus_to_dev(dhd_bus_t *bus)
{
struct pci_dev *pdev;
@ -2306,6 +2269,7 @@ struct device * dhd_bus_to_dev(dhd_bus_t *bus)
else
return NULL;
}
#ifdef HOFFLOAD_MODULES
void
dhd_free_module_memory(struct dhd_bus *bus, struct module_metadata *hmem)

View File

@ -910,6 +910,7 @@ _dhd_pno_convert_format(dhd_pub_t *dhd, struct dhd_pno_batch_params *params_batc
bytes_written = (int32)(bp - buf);
return bytes_written;
}
static int
_dhd_pno_clear_all_batch_results(dhd_pub_t *dhd, struct list_head *head, bool only_last)
{
@ -992,6 +993,7 @@ _dhd_pno_cfg(dhd_pub_t *dhd, uint16 *channel_list, int nchan)
exit:
return err;
}
static int
_dhd_pno_reinitialize_prof(dhd_pub_t *dhd, dhd_pno_params_t *params, dhd_pno_mode_t mode)
{
@ -1084,6 +1086,7 @@ _dhd_pno_reinitialize_prof(dhd_pub_t *dhd, dhd_pno_params_t *params, dhd_pno_mod
mutex_unlock(&_pno_state->pno_mutex);
return err;
}
static int
_dhd_pno_add_bssid(dhd_pub_t *dhd, wl_pfn_bssid_t *p_pfn_bssid, int nbssid)
{
@ -2763,6 +2766,7 @@ _dhd_pno_get_gscan_batch_from_fw(dhd_pub_t *dhd)
return err;
}
#endif /* GSCAN_SUPPORT */
#if defined(GSCAN_SUPPORT) || defined(DHD_GET_VALID_CHANNELS)
void *
dhd_pno_get_gscan(dhd_pub_t *dhd, dhd_pno_gscan_cmd_cfg_t type,
@ -4007,6 +4011,7 @@ int dhd_pno_init(dhd_pub_t *dhd)
kfree(buf);
return err;
}
int dhd_pno_deinit(dhd_pub_t *dhd)
{
int err = BCME_OK;

View File

@ -68,10 +68,6 @@
#include <sdiovar.h>
#include <dhd_config.h>
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/host.h>
#include "bcmsdh_sdmmc.h"
#ifdef PROP_TXSTATUS
#include <dhd_wlfc.h>
#endif
@ -186,12 +182,6 @@ DHD_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep);
pkt_statics_t tx_statics = {0};
#endif
#if defined(MULTIPLE_SUPPLICANT)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
DEFINE_MUTEX(_dhd_sdio_mutex_lock_);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */
#endif
#ifdef SUPPORT_MULTIPLE_BOARD_REV_FROM_HW
extern unsigned int system_hw_rev;
#endif /* SUPPORT_MULTIPLE_BOARD_REV_FROM_HW */
@ -345,6 +335,8 @@ typedef struct dhd_bus {
#if defined(SUPPORT_P2P_GO_PS)
wait_queue_head_t bus_sleep;
#endif /* LINUX && SUPPORT_P2P_GO_PS */
bool ctrl_wait;
wait_queue_head_t ctrl_tx_wait;
uint rxflow_mode; /* Rx flow control mode */
bool rxflow; /* Is rx flow control on */
uint prev_rxlim_hit; /* Is prev rx limit exceeded (per dpc schedule) */
@ -700,7 +692,7 @@ static int dhdsdio_txpkt_preprocess(dhd_bus_t *bus, void *pkt, int chan, int txs
int prev_chain_total_len, bool last_chained_pkt,
int *pad_pkt_len, void **new_pkt
#if defined(BCMSDIOH_TXGLOM_EXT)
, int frist_frame
, int first_frame
#endif
);
static int dhdsdio_txpkt_postprocess(dhd_bus_t *bus, void *pkt);
@ -724,6 +716,7 @@ static int dhd_bcmsdh_send_buffer(void *bus, uint8 *frame, uint16 len);
static int dhdsdio_set_sdmode(dhd_bus_t *bus, int32 sd_mode);
static int dhdsdio_sdclk(dhd_bus_t *bus, bool on);
static void dhdsdio_advertise_bus_cleanup(dhd_pub_t *dhdp);
static void dhdsdio_advertise_bus_remove(dhd_pub_t *dhdp);
#ifdef SUPPORT_MULTIPLE_BOARD_REV_FROM_DT
int dhd_get_system_rev(void);
#endif /* SUPPORT_MULTIPLE_BOARD_REV_FROM_DT */
@ -884,7 +877,8 @@ dhdsdio_sr_cap(dhd_bus_t *bus)
(bus->sih->chip == BCM4371_CHIP_ID) ||
(BCM4349_CHIP(bus->sih->chip)) ||
(bus->sih->chip == BCM4350_CHIP_ID) ||
(bus->sih->chip == BCM43012_CHIP_ID)) {
(bus->sih->chip == BCM43012_CHIP_ID) ||
(bus->sih->chip == BCM4362_CHIP_ID)) {
core_capext = TRUE;
} else {
core_capext = bcmsdh_reg_read(bus->sdh,
@ -980,7 +974,8 @@ dhdsdio_sr_init(dhd_bus_t *bus)
if (CHIPID(bus->sih->chip) == BCM43430_CHIP_ID ||
CHIPID(bus->sih->chip) == BCM43018_CHIP_ID ||
CHIPID(bus->sih->chip) == BCM4339_CHIP_ID ||
CHIPID(bus->sih->chip) == BCM43012_CHIP_ID)
CHIPID(bus->sih->chip) == BCM43012_CHIP_ID ||
CHIPID(bus->sih->chip) == BCM4362_CHIP_ID)
dhdsdio_devcap_set(bus, SDIOD_CCCR_BRCM_CARDCAP_CMD_NODEC);
if (bus->sih->chip == BCM43012_CHIP_ID) {
@ -1048,18 +1043,8 @@ dhdsdio_clk_kso_enab(dhd_bus_t *bus, bool on)
wr_val |= (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT);
{
struct mmc_host *host;
struct sdioh_info *sd = (struct sdioh_info *)(bus->sdh->sdioh);
struct sdio_func *func = sd->func[SDIO_FUNC_0];
bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err);
host = func->card->host;
mmc_retune_disable(host);
bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SLEEPCSR,
wr_val, &err);
mmc_retune_enable(host);
}
/* In case of 43012 chip, the chip could go down immediately after KSO bit is cleared.
* So the further reads of KSO register could fail. Thereby just bailing out immediately
@ -1994,12 +1979,16 @@ dhd_bus_txdata(struct dhd_bus *bus, void *pkt)
prec = PRIO2PREC((PKTPRIO(pkt) & PRIOMASK));
/* move from dhdsdio_sendfromq(), try to orphan skb early */
if (bus->dhd->conf->orphan_move)
PKTORPHAN(pkt, bus->dhd->conf->tsq);
/* Check for existing queue, current flow-control, pending event, or pending clock */
if (dhd_deferred_tx || bus->fcstate || pktq_len(&bus->txq) || bus->dpc_sched ||
(!DATAOK(bus)) || (bus->flowcontrol & NBITVAL(prec)) ||
(bus->clkstate != CLK_AVAIL)) {
bool deq_ret;
int pkq_len;
int pkq_len = 0;
DHD_TRACE(("%s: deferring pktq len %d\n", __FUNCTION__, pktq_len(&bus->txq)));
bus->fcqueued++;
@ -2028,10 +2017,12 @@ dhd_bus_txdata(struct dhd_bus *bus, void *pkt)
} else
ret = BCME_OK;
dhd_os_sdlock_txq(bus->dhd);
pkq_len = pktq_len(&bus->txq);
dhd_os_sdunlock_txq(bus->dhd);
if (pkq_len >= FCHI) {
if (dhd_doflow) {
dhd_os_sdlock_txq(bus->dhd);
pkq_len = pktq_len(&bus->txq);
dhd_os_sdunlock_txq(bus->dhd);
}
if (dhd_doflow && pkq_len >= FCHI) {
bool wlfc_enabled = FALSE;
#ifdef PROP_TXSTATUS
wlfc_enabled = (dhd_wlfc_flowcontrol(bus->dhd, ON, FALSE) !=
@ -2635,7 +2626,8 @@ dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes)
}
}
#endif /* DHD_LOSSLESS_ROAMING */
PKTORPHAN(pkts[i], bus->dhd->conf->tsq);
if (!bus->dhd->conf->orphan_move)
PKTORPHAN(pkts[i], bus->dhd->conf->tsq);
datalen += PKTLEN(osh, pkts[i]);
}
dhd_os_sdunlock_txq(bus->dhd);
@ -2672,9 +2664,11 @@ dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes)
}
dhd_os_sdlock_txq(bus->dhd);
txpktqlen = pktq_len(&bus->txq);
dhd_os_sdunlock_txq(bus->dhd);
if (dhd_doflow) {
dhd_os_sdlock_txq(bus->dhd);
txpktqlen = pktq_len(&bus->txq);
dhd_os_sdunlock_txq(bus->dhd);
}
/* Do flow-control if needed */
if (dhd->up && (dhd->busstate == DHD_BUS_DATA) && (txpktqlen < FCLOW)) {
@ -2727,7 +2721,6 @@ dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen)
uint8 doff = 0;
int ret = -1;
uint8 sdpcm_hdrlen = bus->txglom_enable ? SDPCM_HDRLEN_TXGLOM : SDPCM_HDRLEN;
int cnt = 0;
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
@ -2767,17 +2760,13 @@ dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen)
/* Need to lock here to protect txseq and SDIO tx calls */
retry:
dhd_os_sdlock(bus->dhd);
if (cnt < bus->dhd->conf->txctl_tmo_fix && !TXCTLOK(bus)) {
cnt++;
dhd_os_sdunlock(bus->dhd);
OSL_SLEEP(1);
if (cnt >= (bus->dhd->conf->txctl_tmo_fix))
DHD_ERROR(("%s: No bus credit bus->tx_max %d, bus->tx_seq %d, last retry cnt %d\n",
__FUNCTION__, bus->tx_max, bus->tx_seq, cnt));
goto retry;
if (bus->dhd->conf->txctl_tmo_fix > 0 && !TXCTLOK(bus)) {
bus->ctrl_wait = TRUE;
wait_event_interruptible_timeout(bus->ctrl_tx_wait, TXCTLOK(bus),
msecs_to_jiffies(bus->dhd->conf->txctl_tmo_fix));
bus->ctrl_wait = FALSE;
}
dhd_os_sdlock(bus->dhd);
BUS_WAKE(bus);
@ -2923,6 +2912,7 @@ dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen)
{
int timeleft;
uint rxlen = 0;
static uint cnt = 0;
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
@ -2930,7 +2920,7 @@ dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen)
return -EIO;
/* Wait until control frame is available */
timeleft = dhd_os_ioctl_resp_wait(bus->dhd, &bus->rxlen);
timeleft = dhd_os_ioctl_resp_wait(bus->dhd, &bus->rxlen, false);
dhd_os_sdlock(bus->dhd);
rxlen = bus->rxlen;
@ -2938,6 +2928,32 @@ dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen)
bus->rxlen = 0;
dhd_os_sdunlock(bus->dhd);
if (bus->dhd->conf->ctrl_resched > 0 && !rxlen && timeleft == 0) {
cnt++;
if (cnt <= bus->dhd->conf->ctrl_resched) {
uint32 status, retry = 0;
R_SDREG(status, &bus->regs->intstatus, retry);
if ((status & I_HMB_HOST_INT) || PKT_AVAILABLE(bus, status)) {
DHD_ERROR(("%s: reschedule dhd_dpc, cnt=%d, status=0x%x\n",
__FUNCTION__, cnt, status));
bus->ipend = TRUE;
bus->dpc_sched = TRUE;
dhd_sched_dpc(bus->dhd);
/* Wait until control frame is available */
timeleft = dhd_os_ioctl_resp_wait(bus->dhd, &bus->rxlen, true);
dhd_os_sdlock(bus->dhd);
rxlen = bus->rxlen;
bcopy(bus->rxctl, msg, MIN(msglen, rxlen));
bus->rxlen = 0;
dhd_os_sdunlock(bus->dhd);
}
}
} else {
cnt = 0;
}
if (rxlen) {
DHD_CTL(("%s: resumed on rxctl frame, got %d expected %d\n",
__FUNCTION__, rxlen, msglen));
@ -6832,6 +6848,8 @@ dhdsdio_dpc(dhd_bus_t *bus)
}
}
if (bus->ctrl_wait && TXCTLOK(bus))
wake_up_interruptible(&bus->ctrl_tx_wait);
dhd_os_sdunlock(bus->dhd);
#ifdef DEBUG_DPC_THREAD_WATCHDOG
if (bus->dhd->dhd_bug_on) {
@ -7631,14 +7649,12 @@ dhdsdio_chipmatch(uint16 chipid)
if (chipid == BCM43012_CHIP_ID)
return TRUE;
if (chipid == BCM4362_CHIP_ID)
return TRUE;
return FALSE;
}
#if defined(MULTIPLE_SUPPLICANT)
extern void wl_android_post_init(void); // terence 20120530: fix critical section in dhd_open and dhdsdio_probe
#endif
static void *
dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot,
uint16 func, uint bustype, void *regsva, osl_t * osh, void *sdh)
@ -7649,17 +7665,7 @@ dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot,
struct ether_addr ea_addr;
#endif
#if defined(MULTIPLE_SUPPLICANT)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
if (mutex_is_locked(&_dhd_sdio_mutex_lock_) == 0) {
DHD_ERROR(("%s : no mutex held. set lock\n", __FUNCTION__));
}
else {
DHD_ERROR(("%s : mutex is locked!. wait for unlocking\n", __FUNCTION__));
}
mutex_lock(&_dhd_sdio_mutex_lock_);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */
#endif
DHD_MUTEX_LOCK();
/* Init global variables at run-time, not as part of the declaration.
* This is required to support init/de-init of the driver. Initialization
@ -7741,6 +7747,7 @@ dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot,
#if defined(SUPPORT_P2P_GO_PS)
init_waitqueue_head(&bus->bus_sleep);
#endif /* LINUX && SUPPORT_P2P_GO_PS */
init_waitqueue_head(&bus->ctrl_tx_wait);
/* attempt to attach to the dongle */
if (!(dhdsdio_probe_attach(bus, osh, sdh, regsva, devid))) {
@ -7839,11 +7846,8 @@ dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot,
#if defined(MULTIPLE_SUPPLICANT)
wl_android_post_init(); // terence 20120530: fix critical section in dhd_open and dhdsdio_probe
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
mutex_unlock(&_dhd_sdio_mutex_lock_);
DHD_ERROR(("%s : the lock is released.\n", __FUNCTION__));
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
#endif
#endif /* MULTIPLE_SUPPLICANT */
DHD_MUTEX_UNLOCK();
return bus;
@ -7851,12 +7855,7 @@ dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot,
dhdsdio_release(bus, osh);
forcereturn:
#if defined(MULTIPLE_SUPPLICANT)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
mutex_unlock(&_dhd_sdio_mutex_lock_);
DHD_ERROR(("%s : the lock is released.\n", __FUNCTION__));
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
#endif
DHD_MUTEX_UNLOCK();
return NULL;
}
@ -7910,7 +7909,7 @@ dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva,
bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
DHD_INIT_CLKCTL2, &err);
OSL_DELAY(200);
if (DHD_INFO_ON()) {
for (fn = 0; fn <= numfn; fn++) {
if (!(cis[fn] = MALLOC(osh, SBSDIO_CIS_SIZE_LIMIT))) {
@ -8051,6 +8050,9 @@ dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva,
case BCM4347_CHIP_GRPID:
bus->dongle_ram_base = CR4_4347_RAM_BASE;
break;
case BCM4362_CHIP_ID:
bus->dongle_ram_base = CR4_4362_RAM_BASE;
break;
default:
bus->dongle_ram_base = 0;
DHD_ERROR(("%s: WARNING: Using default ram base at 0x%x\n",
@ -8284,7 +8286,7 @@ dhd_set_path_params(struct dhd_bus *bus)
dhd_conf_read_config(bus->dhd, bus->dhd->conf_path);
dhd_conf_set_fw_name_by_chip(bus->dhd, bus->fw_path, bus->nv_path);
dhd_conf_set_fw_name_by_chip(bus->dhd, bus->fw_path);
dhd_conf_set_nv_name_by_chip(bus->dhd, bus->nv_path);
dhd_conf_set_clm_name_by_chip(bus->dhd, bus->dhd->clm_path);
@ -8309,15 +8311,12 @@ dhd_set_bus_params(struct dhd_bus *bus)
}
if (bus->dhd->conf->use_rxchain >= 0) {
bus->use_rxchain = (bool)bus->dhd->conf->use_rxchain;
printf("%s: set use_rxchain %d\n", __FUNCTION__, bus->dhd->conf->use_rxchain);
}
if (bus->dhd->conf->txinrx_thres >= 0) {
bus->txinrx_thres = bus->dhd->conf->txinrx_thres;
printf("%s: set txinrx_thres %d\n", __FUNCTION__, bus->txinrx_thres);
}
if (bus->dhd->conf->txglomsize >= 0) {
bus->txglomsize = bus->dhd->conf->txglomsize;
printf("%s: set txglomsize %d\n", __FUNCTION__, bus->dhd->conf->txglomsize);
}
}
@ -8462,33 +8461,14 @@ dhdsdio_disconnect(void *ptr)
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
#if defined(MULTIPLE_SUPPLICANT)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
if (mutex_is_locked(&_dhd_sdio_mutex_lock_) == 0) {
DHD_ERROR(("%s : no mutex held. set lock\n", __FUNCTION__));
}
else {
DHD_ERROR(("%s : mutex is locked!. wait for unlocking\n", __FUNCTION__));
}
mutex_lock(&_dhd_sdio_mutex_lock_);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */
#endif
DHD_MUTEX_LOCK();
if (bus) {
ASSERT(bus->dhd);
/* Advertise bus cleanup during rmmod */
dhdsdio_advertise_bus_cleanup(bus->dhd);
/* Advertise bus remove during rmmod */
dhdsdio_advertise_bus_remove(bus->dhd);
dhdsdio_release(bus, bus->dhd->osh);
}
#if defined(MULTIPLE_SUPPLICANT)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
mutex_unlock(&_dhd_sdio_mutex_lock_);
DHD_ERROR(("%s : the lock is released.\n", __FUNCTION__));
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */
#endif /* LINUX */
DHD_MUTEX_UNLOCK();
DHD_TRACE(("%s: Disconnected\n", __FUNCTION__));
}
@ -9262,6 +9242,27 @@ dhdsdio_advertise_bus_cleanup(dhd_pub_t *dhdp)
return;
}
static void
dhdsdio_advertise_bus_remove(dhd_pub_t *dhdp)
{
unsigned long flags;
int timeleft;
DHD_LINUX_GENERAL_LOCK(dhdp, flags);
dhdp->busstate = DHD_BUS_REMOVE;
DHD_LINUX_GENERAL_UNLOCK(dhdp, flags);
timeleft = dhd_os_busbusy_wait_negation(dhdp, &dhdp->dhd_bus_busy_state);
if ((timeleft == 0) || (timeleft == 1)) {
DHD_ERROR(("%s : Timeout due to dhd_bus_busy_state=0x%x\n",
__FUNCTION__, dhdp->dhd_bus_busy_state));
ASSERT(0);
}
return;
}
int
dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag)
{

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
@ -7,7 +7,7 @@
#include <linux/err.h>
#include <linux/skbuff.h>
#define DHD_STATIC_VERSION_STR "1.579.77.41.1"
#define DHD_STATIC_VERSION_STR "1.579.77.41.9"
#define BCMDHD_SDIO
#define BCMDHD_PCIE
@ -53,7 +53,7 @@ enum dhd_prealloc_index {
#define DHD_PREALLOC_OSL_BUF_SIZE (STATIC_BUF_MAX_NUM * STATIC_BUF_SIZE)
#define DHD_PREALLOC_WIPHY_ESCAN0_SIZE (64 * 1024)
#define DHD_PREALLOC_DHD_INFO_SIZE (30 * 1024)
#define DHD_PREALLOC_MEMDUMP_RAM_SIZE (770 * 1024)
#define DHD_PREALLOC_MEMDUMP_RAM_SIZE (810 * 1024)
#define DHD_PREALLOC_DHD_WLFC_HANGER_SIZE (73 * 1024)
#define DHD_PREALLOC_WL_ESCAN_INFO_SIZE (66 * 1024)
#ifdef CONFIG_64BIT
@ -327,6 +327,8 @@ static int dhd_init_wlan_mem(void)
wlan_static_if_flow_lkup = kmalloc(DHD_PREALLOC_IF_FLOW_LKUP_SIZE, GFP_KERNEL);
if (!wlan_static_if_flow_lkup)
goto err_mem_alloc;
pr_err("%s: sectoin %d, size=%d\n", __func__,
DHD_PREALLOC_IF_FLOW_LKUP, DHD_PREALLOC_IF_FLOW_LKUP_SIZE);
#endif /* BCMDHD_PCIE */
wlan_static_dhd_memdump_ram_buf = kmalloc(DHD_PREALLOC_MEMDUMP_RAM_SIZE, GFP_KERNEL);
@ -347,31 +349,29 @@ static int dhd_init_wlan_mem(void)
pr_err("%s: sectoin %d, size=%d\n", __func__,
DHD_PREALLOC_WL_ESCAN_INFO, DHD_PREALLOC_WL_ESCAN_INFO_SIZE);
wlan_static_fw_verbose_ring_buf = kmalloc(
DHD_PREALLOC_WIPHY_ESCAN0_SIZE,
GFP_KERNEL);
wlan_static_fw_verbose_ring_buf = kmalloc(FW_VERBOSE_RING_SIZE, GFP_KERNEL);
if (!wlan_static_fw_verbose_ring_buf)
goto err_mem_alloc;
pr_err("%s: sectoin %d, size=%d\n", __func__,
DHD_PREALLOC_FW_VERBOSE_RING, DHD_PREALLOC_WL_ESCAN_INFO_SIZE);
DHD_PREALLOC_FW_VERBOSE_RING, FW_VERBOSE_RING_SIZE);
wlan_static_fw_event_ring_buf = kmalloc(DHD_PREALLOC_WIPHY_ESCAN0_SIZE, GFP_KERNEL);
wlan_static_fw_event_ring_buf = kmalloc(FW_EVENT_RING_SIZE, GFP_KERNEL);
if (!wlan_static_fw_event_ring_buf)
goto err_mem_alloc;
pr_err("%s: sectoin %d, size=%d\n", __func__,
DHD_PREALLOC_FW_EVENT_RING, DHD_PREALLOC_WL_ESCAN_INFO_SIZE);
DHD_PREALLOC_FW_EVENT_RING, FW_EVENT_RING_SIZE);
wlan_static_dhd_event_ring_buf = kmalloc(DHD_PREALLOC_WIPHY_ESCAN0_SIZE, GFP_KERNEL);
wlan_static_dhd_event_ring_buf = kmalloc(DHD_EVENT_RING_SIZE, GFP_KERNEL);
if (!wlan_static_dhd_event_ring_buf)
goto err_mem_alloc;
pr_err("%s: sectoin %d, size=%d\n", __func__,
DHD_PREALLOC_DHD_EVENT_RING, DHD_PREALLOC_WL_ESCAN_INFO_SIZE);
DHD_PREALLOC_DHD_EVENT_RING, DHD_EVENT_RING_SIZE);
wlan_static_nan_event_ring_buf = kmalloc(DHD_PREALLOC_WIPHY_ESCAN0_SIZE, GFP_KERNEL);
wlan_static_nan_event_ring_buf = kmalloc(NAN_EVENT_RING_SIZE, GFP_KERNEL);
if (!wlan_static_nan_event_ring_buf)
goto err_mem_alloc;
pr_err("%s: sectoin %d, size=%d\n", __func__,
DHD_PREALLOC_NAN_EVENT_RING, DHD_PREALLOC_WL_ESCAN_INFO_SIZE);
DHD_PREALLOC_NAN_EVENT_RING, NAN_EVENT_RING_SIZE);
return 0;

View File

@ -1617,7 +1617,7 @@ _dhd_wlfc_pktq_flush(athost_wl_status_info_t* ctx, struct pktq *pq,
ASSERT(pq->len == 0);
} /* _dhd_wlfc_pktq_flush */
#ifndef BCMDBUS
/** !BCMDBUS specific function. Dequeues a packet from the caller supplied queue. */
static void*
_dhd_wlfc_pktq_pdeq_with_fn(struct pktq *pq, int prec, f_processpkt_t fn, void *arg)
@ -1723,6 +1723,7 @@ _dhd_wlfc_cleanup_txq(dhd_pub_t *dhd, f_processpkt_t fn, void *arg)
PKTFREE(wlfc->osh, pkt, TRUE);
}
} /* _dhd_wlfc_cleanup_txq */
#endif /* !BCMDBUS */
/** called during eg detach */
void
@ -1741,8 +1742,10 @@ _dhd_wlfc_cleanup(dhd_pub_t *dhd, f_processpkt_t fn, void *arg)
/*
* flush sequence should be txq -> psq -> hanger/afq, hanger has to be last one
*/
#ifndef BCMDBUS
/* flush bus->txq */
_dhd_wlfc_cleanup_txq(dhd, fn, arg);
#endif /* !BCMDBUS */
/* flush psq, search all entries, include nodes as well as interfaces */
total_entries = sizeof(wlfc->destination_entries)/sizeof(wlfc_mac_descriptor_t);
@ -2465,7 +2468,7 @@ _dhd_wlfc_fifocreditback_indicate(dhd_pub_t *dhd, uint8* credits)
return BCME_OK;
} /* _dhd_wlfc_fifocreditback_indicate */
#ifndef BCMDBUS
/** !BCMDBUS specific function */
static void
_dhd_wlfc_suppress_txq(dhd_pub_t *dhd, f_processpkt_t fn, void *arg)
@ -2544,6 +2547,7 @@ _dhd_wlfc_suppress_txq(dhd_pub_t *dhd, f_processpkt_t fn, void *arg)
_dhd_wlfc_fifocreditback_indicate(dhd, credits);
}
} /* _dhd_wlfc_suppress_txq */
#endif /* !BCMDBUS */
static int
_dhd_wlfc_dbg_senum_check(dhd_pub_t *dhd, uint8 *value)
@ -3072,10 +3076,12 @@ dhd_wlfc_parse_header_info(dhd_pub_t *dhd, void* pktbuf, int tlv_hdr_len, uchar
_dhd_wlfc_interface_update(dhd, value, type);
}
#ifndef BCMDBUS
if (entry && WLFC_GET_REORDERSUPP(dhd->wlfc_mode)) {
/* suppress all packets for this mac entry from bus->txq */
_dhd_wlfc_suppress_txq(dhd, _dhd_wlfc_entrypkt_fn, entry);
}
#endif /* !BCMDBUS */
} /* while */
if (remainder != 0 && wlfc) {
@ -3407,6 +3413,15 @@ dhd_wlfc_commit_packets(dhd_pub_t *dhdp, f_commitpkt_t fcommit, void* commit_ctx
ctx = (athost_wl_status_info_t*)dhdp->wlfc_state;
#ifdef BCMDBUS
if (!dhdp->up || (dhdp->busstate == DHD_BUS_DOWN)) {
if (pktbuf) {
PKTFREE(ctx->osh, pktbuf, TRUE);
rc = BCME_OK;
}
goto exit;
}
#endif /* BCMDBUS */
if (dhdp->proptxstatus_module_ignore) {
if (pktbuf) {
@ -3593,10 +3608,17 @@ dhd_wlfc_init(dhd_pub_t *dhd)
DHD_ERROR(("%s: query wlfc_mode succeed, fw_caps=0x%x\n", __FUNCTION__, fw_caps));
if (WLFC_IS_OLD_DEF(fw_caps)) {
#ifdef BCMDBUS
mode = WLFC_MODE_HANGER;
#else
/* enable proptxtstatus v2 by default */
mode = WLFC_MODE_AFQ;
#endif /* BCMDBUS */
} else {
WLFC_SET_AFQ(mode, WLFC_GET_AFQ(fw_caps));
#ifdef BCMDBUS
WLFC_SET_AFQ(mode, 0);
#endif /* BCMDBUS */
WLFC_SET_REUSESEQ(mode, WLFC_GET_REUSESEQ(fw_caps));
WLFC_SET_REORDERSUPP(mode, WLFC_GET_REORDERSUPP(fw_caps));
}
@ -3679,7 +3701,9 @@ dhd_wlfc_cleanup_txq(dhd_pub_t *dhd, f_processpkt_t fn, void *arg)
return WLFC_UNSUPPORTED;
}
#ifndef BCMDBUS
_dhd_wlfc_cleanup_txq(dhd, fn, arg);
#endif /* !BCMDBUS */
dhd_os_wlfc_unblock(dhd);

View File

@ -111,8 +111,13 @@ typedef struct wlfc_hanger {
#define WLFC_PSQ_LEN (4096 * 8)
#ifdef BCMDBUS
#define WLFC_FLOWCONTROL_HIWATER 512
#define WLFC_FLOWCONTROL_LOWATER (WLFC_FLOWCONTROL_HIWATER / 4)
#else
#define WLFC_FLOWCONTROL_HIWATER ((4096 * 8) - 256)
#define WLFC_FLOWCONTROL_LOWATER 256
#endif
#if (WLFC_FLOWCONTROL_HIWATER >= (WLFC_PSQ_LEN - 256))
#undef WLFC_FLOWCONTROL_HIWATER

View File

@ -280,6 +280,10 @@
#define BCM4361_D11AC2G_ID 0x4420 /* 4361 802.11ac 2.4G device */
#define BCM4361_D11AC5G_ID 0x4421 /* 4361 802.11ac 5G device */
#define BCM4362_D11AX_ID 0x4490 /* 4362 802.11ax dualband device */
#define BCM4362_D11AX2G_ID 0x4491 /* 4362 802.11ax 2.4G device */
#define BCM4362_D11AX5G_ID 0x4492 /* 4362 802.11ax 5G device */
#define BCM4364_D11AC_ID 0x4464 /* 4364 802.11ac dualband device */
#define BCM4364_D11AC2G_ID 0x446a /* 4364 802.11ac 2.4G device */
#define BCM4364_D11AC5G_ID 0x446b /* 4364 802.11ac 5G device */
@ -501,6 +505,7 @@
#define BCM4347_CHIP_ID 0x4347 /* 4347 chipcommon chipid */
#define BCM4357_CHIP_ID 0x4357 /* 4357 chipcommon chipid */
#define BCM4361_CHIP_ID 0x4361 /* 4361 chipcommon chipid */
#define BCM4362_CHIP_ID 0x4362 /* 4362 chipcommon chipid */
#define BCM4347_CHIP(chipid) ((CHIPID(chipid) == BCM4347_CHIP_ID) || \
(CHIPID(chipid) == BCM4357_CHIP_ID) || \
(CHIPID(chipid) == BCM4361_CHIP_ID))

View File

@ -32,11 +32,22 @@
#define __DBUS_H__
#include "typedefs.h"
#include <dhd_linux.h>
#define DBUSTRACE(args)
extern uint dbus_msglevel;
#define DBUS_ERROR_VAL 0x0001
#define DBUS_TRACE_VAL 0x0002
#define DBUS_INFO_VAL 0x0004
#if defined(DHD_DEBUG)
#define DBUSERR(args) do {if (dbus_msglevel & DBUS_ERROR_VAL) printf args;} while (0)
#define DBUSTRACE(args) do {if (dbus_msglevel & DBUS_TRACE_VAL) printf args;} while (0)
#define DBUSINFO(args) do {if (dbus_msglevel & DBUS_INFO_VAL) printf args;} while (0)
#else /* defined(DHD_DEBUG) */
#define DBUSERR(args)
#define DBUSTRACE(args)
#define DBUSINFO(args)
#define DBUSDBGLOCK(args)
#endif
enum {
DBUS_OK = 0,
@ -181,7 +192,8 @@ typedef struct dbus_extdl {
struct dbus_callbacks;
struct exec_parms;
typedef void *(*probe_cb_t)(void *arg, const char *desc, uint32 bustype, uint32 hdrlen);
typedef void *(*probe_cb_t)(void *arg, const char *desc, uint32 bustype,
uint16 bus_no, uint16 slot, uint32 hdrlen);
typedef void (*disconnect_cb_t)(void *arg);
typedef void *(*exec_cb_t)(struct exec_parms *args);
@ -237,7 +249,7 @@ typedef struct {
int (*get_config)(void *bus, dbus_config_t *config);
bool (*device_exists)(void *bus);
bool (*dlneeded)(void *bus);
int (*dlneeded)(void *bus);
int (*dlstart)(void *bus, uint8 *fw, int len);
int (*dlrun)(void *bus);
bool (*recv_needed)(void *bus);
@ -299,26 +311,21 @@ extern int dbus_register(int vid, int pid, probe_cb_t prcb, disconnect_cb_t disc
void *param1, void *param2);
extern int dbus_deregister(void);
extern dbus_pub_t *dbus_attach(struct osl_info *osh, int rxsize, int nrxq, int ntxq,
void *cbarg, dbus_callbacks_t *cbs, dbus_extdl_t *extdl, struct shared_info *sh);
extern void dbus_detach(dbus_pub_t *pub);
extern int dbus_download_firmware(dbus_pub_t *pub);
extern int dbus_up(dbus_pub_t *pub);
//extern int dbus_download_firmware(dbus_pub_t *pub);
//extern int dbus_up(struct dhd_bus *pub);
extern int dbus_down(dbus_pub_t *pub);
extern int dbus_stop(dbus_pub_t *pub);
//extern int dbus_stop(struct dhd_bus *pub);
extern int dbus_shutdown(dbus_pub_t *pub);
extern void dbus_flowctrl_rx(dbus_pub_t *pub, bool on);
extern int dbus_send_txdata(dbus_pub_t *dbus, void *pktbuf);
extern int dbus_send_buf(dbus_pub_t *pub, uint8 *buf, int len, void *info);
extern int dbus_send_pkt(dbus_pub_t *pub, void *pkt, void *info);
extern int dbus_send_ctl(dbus_pub_t *pub, uint8 *buf, int len);
extern int dbus_recv_ctl(dbus_pub_t *pub, uint8 *buf, int len);
//extern int dbus_send_ctl(struct dhd_bus *pub, uint8 *buf, int len);
//extern int dbus_recv_ctl(struct dhd_bus *pub, uint8 *buf, int len);
extern int dbus_recv_bulk(dbus_pub_t *pub, uint32 ep_idx);
extern int dbus_poll_intr(dbus_pub_t *pub);
extern int dbus_get_stats(dbus_pub_t *pub, dbus_stats_t *stats);
extern int dbus_get_attrib(dbus_pub_t *pub, dbus_attrib_t *attrib);
extern int dbus_get_device_speed(dbus_pub_t *pub);
extern int dbus_set_config(dbus_pub_t *pub, dbus_config_t *config);
extern int dbus_get_config(dbus_pub_t *pub, dbus_config_t *config);
@ -332,8 +339,8 @@ extern int dbus_pnp_sleep(dbus_pub_t *pub);
extern int dbus_pnp_resume(dbus_pub_t *pub, int *fw_reload);
extern int dbus_pnp_disconnect(dbus_pub_t *pub);
extern int dbus_iovar_op(dbus_pub_t *pub, const char *name,
void *params, int plen, void *arg, int len, bool set);
//extern int dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name,
// void *params, int plen, void *arg, int len, bool set);
extern void *dhd_dbus_txq(const dbus_pub_t *pub);
extern uint dhd_dbus_hdrlen(const dbus_pub_t *pub);

View File

@ -46,6 +46,6 @@
#define EPI_VERSION_DEV 1.579.77.41
/* Driver Version String, ASCII, 32 chars max */
#define EPI_VERSION_STR "1.579.77.41.2 (r)"
#define EPI_VERSION_STR "1.579.77.41.9 (r)"
#endif /* _epivers_h_ */

View File

@ -1145,6 +1145,7 @@ typedef struct sk_buff_head PKT_LIST;
#define PKTLIST_UNLINK(x, y) skb_unlink((struct sk_buff *)(y), (struct sk_buff_head *)(x))
#define PKTLIST_FINI(x) skb_queue_purge((struct sk_buff_head *)(x))
#ifdef REPORT_FATAL_TIMEOUTS
typedef struct osl_timer {
struct timer_list *timer;
bool set;
@ -1156,5 +1157,6 @@ extern osl_timer_t * osl_timer_init(osl_t *osh, const char *name, void (*fn)(voi
extern void osl_timer_add(osl_t *osh, osl_timer_t *t, uint32 ms, bool periodic);
extern void osl_timer_update(osl_t *osh, osl_timer_t *t, uint32 ms, bool periodic);
extern bool osl_timer_del(osl_t *osh, osl_timer_t *t);
#endif
#endif /* _linux_osl_h_ */

View File

@ -3343,6 +3343,7 @@ typedef volatile struct {
#define CA7_4365_RAM_BASE (0x200000)
#define CR4_4347_RAM_BASE (0x170000)
#define CR4_4362_RAM_BASE (0x170000)
/* 4335 chip OTP present & OTP select bits. */
#define SPROM4335_OTP_SELECT 0x00000010

View File

@ -0,0 +1,135 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Broadcom USB remote download definitions
*
* Copyright (C) 1999-2016, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
* under the terms of the GNU General Public License version 2 (the "GPL"),
* available at http://www.broadcom.com/licenses/GPLv2.php, with the
* following added to such license:
*
* As a special exception, the copyright holders of this software give you
* permission to link this software with independent modules, and to copy and
* distribute the resulting executable under terms of your choice, provided that
* you also meet, for each linked independent module, the terms and conditions of
* the license of that module. An independent module is a module which is not
* derived from this software. The special exception does not apply to any
* modifications of the software.
*
* Notwithstanding the above, under no circumstances may you combine this
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
*
* <<Broadcom-WL-IPTag/Open:>>
*
* $Id: usbrdl.h 597933 2015-11-06 18:52:06Z $
*/
#ifndef _USB_RDL_H
#define _USB_RDL_H
/* Control messages: bRequest values */
#define DL_GETSTATE 0 /* returns the rdl_state_t struct */
#define DL_CHECK_CRC 1 /* currently unused */
#define DL_GO 2 /* execute downloaded image */
#define DL_START 3 /* initialize dl state */
#define DL_REBOOT 4 /* reboot the device in 2 seconds */
#define DL_GETVER 5 /* returns the bootrom_id_t struct */
#define DL_GO_PROTECTED 6 /* execute the downloaded code and set reset event
* to occur in 2 seconds. It is the responsibility
* of the downloaded code to clear this event
*/
#define DL_EXEC 7 /* jump to a supplied address */
#define DL_RESETCFG 8 /* To support single enum on dongle
* - Not used by bootloader
*/
#define DL_DEFER_RESP_OK 9 /* Potentially defer the response to setup
* if resp unavailable
*/
#define DL_CHGSPD 0x0A
#define DL_HWCMD_MASK 0xfc /* Mask for hardware read commands: */
#define DL_RDHW 0x10 /* Read a hardware address (Ctl-in) */
#define DL_RDHW32 0x10 /* Read a 32 bit word */
#define DL_RDHW16 0x11 /* Read 16 bits */
#define DL_RDHW8 0x12 /* Read an 8 bit byte */
#define DL_WRHW 0x14 /* Write a hardware address (Ctl-out) */
#define DL_WRHW_BLK 0x13 /* Block write to hardware access */
#define DL_CMD_WRHW 2
/* states */
#define DL_WAITING 0 /* waiting to rx first pkt that includes the hdr info */
#define DL_READY 1 /* hdr was good, waiting for more of the compressed image */
#define DL_BAD_HDR 2 /* hdr was corrupted */
#define DL_BAD_CRC 3 /* compressed image was corrupted */
#define DL_RUNNABLE 4 /* download was successful, waiting for go cmd */
#define DL_START_FAIL 5 /* failed to initialize correctly */
#define DL_NVRAM_TOOBIG 6 /* host specified nvram data exceeds DL_NVRAM value */
#define DL_IMAGE_TOOBIG 7 /* download image too big (exceeds DATA_START for rdl) */
#define TIMEOUT 5000 /* Timeout for usb commands */
struct bcm_device_id {
char *name;
uint32 vend;
uint32 prod;
};
typedef struct {
uint32 state;
uint32 bytes;
} rdl_state_t;
typedef struct {
uint32 chip; /* Chip id */
uint32 chiprev; /* Chip rev */
uint32 ramsize; /* Size of RAM */
uint32 remapbase; /* Current remap base address */
uint32 boardtype; /* Type of board */
uint32 boardrev; /* Board revision */
} bootrom_id_t;
/* struct for backplane & jtag accesses */
typedef struct {
uint32 cmd; /* tag to identify the cmd */
uint32 addr; /* backplane address for write */
uint32 len; /* length of data: 1, 2, 4 bytes */
uint32 data; /* data to write */
} hwacc_t;
/* struct for querying nvram params from bootloader */
#define QUERY_STRING_MAX 32
typedef struct {
uint32 cmd; /* tag to identify the cmd */
char var[QUERY_STRING_MAX]; /* param name */
} nvparam_t;
typedef void (*exec_fn_t)(void *sih);
#define USB_CTRL_IN (USB_TYPE_VENDOR | 0x80 | USB_RECIP_INTERFACE)
#define USB_CTRL_OUT (USB_TYPE_VENDOR | 0 | USB_RECIP_INTERFACE)
#define USB_CTRL_EP_TIMEOUT 500 /* Timeout used in USB control_msg transactions. */
#define USB_BULK_EP_TIMEOUT 500 /* Timeout used in USB bulk transactions. */
#define RDL_CHUNK_MAX (64 * 1024) /* max size of each dl transfer */
#define RDL_CHUNK 1500 /* size of each dl transfer */
/* bootloader makes special use of trx header "offsets" array */
#define TRX_OFFSETS_DLFWLEN_IDX 0 /* Size of the fw; used in uncompressed case */
#define TRX_OFFSETS_JUMPTO_IDX 1 /* RAM address for jumpto after download */
#define TRX_OFFSETS_NVM_LEN_IDX 2 /* Length of appended NVRAM data */
#ifdef BCMTRXV2
#define TRX_OFFSETS_DSG_LEN_IDX 3 /* Length of digital signature for the first image */
#define TRX_OFFSETS_CFG_LEN_IDX 4 /* Length of config region, which is not digitally signed */
#endif /* BCMTRXV2 */
#define TRX_OFFSETS_DLBASE_IDX 0 /* RAM start address for download */
#endif /* _USB_RDL_H */

View File

@ -11548,6 +11548,15 @@ typedef enum wl_interface_type {
*/
#define WL_INTERFACE_BSSID_INDEX_USE (1 << 4)
#ifdef WLMESH
typedef struct wl_interface_info {
uint16 ver; /* version of this struct */
struct ether_addr mac_addr; /* MAC address of the interface */
char ifname[BCM_MSG_IFNAME_MAX]; /* name of interface */
uint8 bsscfgidx; /* source bsscfg index */
} wl_interface_info_t;
#endif
typedef struct wl_interface_create {
uint16 ver; /* version of this struct */
uint32 flags; /* flags that defines the operation */
@ -12462,6 +12471,12 @@ enum wl_mesh_cmd_xtlv_id {
};
/* endif WLMESH */
#ifdef WLMESH
#ifndef SAE_MAX_PASSWD_LEN
#define SAE_MAX_PASSWD_LEN 32
#endif
#endif
/* Fast BSS Transition parameter configuration */
#define FBT_PARAM_CURRENT_VERSION 0

View File

@ -2148,9 +2148,13 @@ osl_os_get_image_block(char *buf, int len, void *image)
if (!image)
return 0;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
rdlen = kernel_read(fp, buf, len, &fp->f_pos);
#else
rdlen = kernel_read(fp, fp->f_pos, buf, len);
if (rdlen > 0)
fp->f_pos += rdlen;
#endif
return rdlen;
}
@ -2677,13 +2681,19 @@ osl_pkt_orphan_partial(struct sk_buff *skb, int tsq)
*/
fraction = skb->truesize * (tsq - 1) / tsq;
skb->truesize -= fraction;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
atomic_sub(fraction, &skb->sk->sk_wmem_alloc.refs);
#else
atomic_sub(fraction, &skb->sk->sk_wmem_alloc);
#endif /* LINUX_VERSION >= 4.13.0 */
skb_orphan(skb);
}
#endif /* LINUX_VERSION >= 3.6.0 && TSQ_MULTIPLIER */
/* timer apis */
/* Note: All timer api's are thread unsafe and should be protected with locks by caller */
#ifdef REPORT_FATAL_TIMEOUTS
osl_timer_t *
osl_timer_init(osl_t *osh, const char *name, void (*fn)(void *arg), void *arg)
{
@ -2768,3 +2778,4 @@ osl_timer_del(osl_t *osh, osl_timer_t *t)
}
return (TRUE);
}
#endif

View File

@ -604,7 +604,6 @@ si_doattach(si_info_t *sii, uint devid, osl_t *osh, volatile void *regs,
}
sih->bustype = bustype;
#ifdef BCMBUSTYPE
if (bustype != BUSTYPE(bustype)) {
SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n",
@ -636,7 +635,7 @@ si_doattach(si_info_t *sii, uint devid, osl_t *osh, volatile void *regs,
sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
#if defined(HW_OOB) || defined(FORCE_WOWLAN)
#if defined(BCMSDIO) && (defined(HW_OOB) || defined(FORCE_WOWLAN))
dhd_conf_set_hw_oob_intr(sdh, sih->chip);
#endif

View File

@ -104,6 +104,10 @@ uint android_msg_level = ANDROID_ERROR_LEVEL;
#define CMD_SETBAND "SETBAND"
#define CMD_GETBAND "GETBAND"
#define CMD_COUNTRY "COUNTRY"
#ifdef WLMESH
#define CMD_SAE_SET_PASSWORD "SAE_SET_PASSWORD"
#define CMD_SET_RSDB_MODE "RSDB_MODE"
#endif
#define CMD_P2P_SET_NOA "P2P_SET_NOA"
#if !defined WL_ENABLE_P2P_IF
#define CMD_P2P_GET_NOA "P2P_GET_NOA"
@ -1068,7 +1072,7 @@ wl_cfg80211_get_sta_info(struct net_device *dev, char* command, int total_len)
error:
return bytes_written;
}
#endif /* CUSTOMER_HW4_PRIVATE_CMD */
#endif
#ifdef WBTEXT
static int wl_android_wbtext(struct net_device *dev, char *command, int total_len)
@ -1179,6 +1183,7 @@ static int wl_cfg80211_wbtext_btm_delta(struct net_device *dev,
#define PNO_PARAM_SIZE 50
#define VALUE_SIZE 50
#define LIMIT_STR_FMT ("%50s %50s")
static int
wls_parse_batching_cmd(struct net_device *dev, char *command, int total_len)
{
@ -1187,7 +1192,8 @@ wls_parse_batching_cmd(struct net_device *dev, char *command, int total_len)
char *pos, *pos2, *token, *token2, *delim;
char param[PNO_PARAM_SIZE+1], value[VALUE_SIZE+1];
struct dhd_pno_batch_params batch_params;
DHD_PNO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
ANDROID_INFO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
if (total_len < strlen(CMD_WLS_BATCHING)) {
ANDROID_ERROR(("%s argument=%d less min size\n", __FUNCTION__, total_len));
err = BCME_ERROR;
@ -1212,13 +1218,13 @@ wls_parse_batching_cmd(struct net_device *dev, char *command, int total_len)
tokens = sscanf(token, LIMIT_STR_FMT, param, value);
if (!strncmp(param, PNO_PARAM_SCANFREQ, strlen(PNO_PARAM_SCANFREQ))) {
batch_params.scan_fr = simple_strtol(value, NULL, 0);
DHD_PNO(("scan_freq : %d\n", batch_params.scan_fr));
ANDROID_INFO(("scan_freq : %d\n", batch_params.scan_fr));
} else if (!strncmp(param, PNO_PARAM_BESTN, strlen(PNO_PARAM_BESTN))) {
batch_params.bestn = simple_strtol(value, NULL, 0);
DHD_PNO(("bestn : %d\n", batch_params.bestn));
ANDROID_INFO(("bestn : %d\n", batch_params.bestn));
} else if (!strncmp(param, PNO_PARAM_MSCAN, strlen(PNO_PARAM_MSCAN))) {
batch_params.mscan = simple_strtol(value, NULL, 0);
DHD_PNO(("mscan : %d\n", batch_params.mscan));
ANDROID_INFO(("mscan : %d\n", batch_params.mscan));
} else if (!strncmp(param, PNO_PARAM_CHANNEL, strlen(PNO_PARAM_CHANNEL))) {
i = 0;
pos2 = value;
@ -1238,7 +1244,7 @@ wls_parse_batching_cmd(struct net_device *dev, char *command, int total_len)
if (*token2 == 'A' || *token2 == 'B') {
batch_params.band = (*token2 == 'A')?
WLC_BAND_5G : WLC_BAND_2G;
DHD_PNO(("band : %s\n",
ANDROID_INFO(("band : %s\n",
(*token2 == 'A')? "A" : "B"));
} else {
if ((batch_params.nchan >= WL_NUMCHANNELS) ||
@ -1251,13 +1257,13 @@ wls_parse_batching_cmd(struct net_device *dev, char *command, int total_len)
batch_params.chan_list[i++] =
simple_strtol(token2, NULL, 0);
batch_params.nchan++;
DHD_PNO(("channel :%d\n",
ANDROID_INFO(("channel :%d\n",
batch_params.chan_list[i-1]));
}
}
} else if (!strncmp(param, PNO_PARAM_RTT, strlen(PNO_PARAM_RTT))) {
batch_params.rtt = simple_strtol(value, NULL, 0);
DHD_PNO(("rtt : %d\n", batch_params.rtt));
ANDROID_INFO(("rtt : %d\n", batch_params.rtt));
} else {
ANDROID_ERROR(("%s : unknown param: %s\n", __FUNCTION__, param));
err = BCME_ERROR;
@ -1294,6 +1300,7 @@ wls_parse_batching_cmd(struct net_device *dev, char *command, int total_len)
exit:
return err;
}
#ifndef WL_SCHED_SCAN
static int wl_android_set_pno_setup(struct net_device *dev, char *command, int total_len)
{
@ -1327,7 +1334,7 @@ static int wl_android_set_pno_setup(struct net_device *dev, char *command, int t
0x00
};
#endif /* PNO_SET_DEBUG */
DHD_PNO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
ANDROID_INFO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
if (total_len < (strlen(CMD_PNOSETUP_SET) + sizeof(cmd_tlv_t))) {
ANDROID_ERROR(("%s argument=%d less min size\n", __FUNCTION__, total_len));
@ -1362,7 +1369,7 @@ static int wl_android_set_pno_setup(struct net_device *dev, char *command, int t
}
str_ptr++;
pno_time = simple_strtoul(str_ptr, &str_ptr, 16);
DHD_PNO(("%s: pno_time=%d\n", __FUNCTION__, pno_time));
ANDROID_INFO(("%s: pno_time=%d\n", __FUNCTION__, pno_time));
if (str_ptr[0] != 0) {
if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) {
@ -1372,7 +1379,7 @@ static int wl_android_set_pno_setup(struct net_device *dev, char *command, int t
}
str_ptr++;
pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16);
DHD_PNO(("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat));
ANDROID_INFO(("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat));
if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) {
ANDROID_ERROR(("%s FREQ_EXPO_MAX corrupted field size\n",
__FUNCTION__));
@ -1380,7 +1387,7 @@ static int wl_android_set_pno_setup(struct net_device *dev, char *command, int t
}
str_ptr++;
pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16);
DHD_PNO(("%s: pno_freq_expo_max=%d\n",
ANDROID_INFO(("%s: pno_freq_expo_max=%d\n",
__FUNCTION__, pno_freq_expo_max));
}
}
@ -1552,10 +1559,6 @@ int wl_android_wifi_on(struct net_device *dev)
{
int ret = 0;
int retry = POWERUP_MAX_RETRY;
#ifdef IAPSTA_PREINIT
int bytes_written = 0;
struct dhd_conf *conf;
#endif
if (!dev) {
ANDROID_ERROR(("%s: dev is null\n", __FUNCTION__));
@ -1589,30 +1592,22 @@ int wl_android_wifi_on(struct net_device *dev)
ANDROID_ERROR(("\nfailed to power up wifi chip, max retry reached **\n\n"));
goto exit;
}
#ifdef BCMSDIO
#if defined(BCMSDIO) || defined(BCMDBUS)
ret = dhd_net_bus_devreset(dev, FALSE);
if (ret)
goto err;
#ifdef BCMSDIO
dhd_net_bus_resume(dev, 1);
#endif /* BCMSDIO */
#ifndef BCMPCIE
#endif /* BCMSDIO || BCMDBUS */
#if defined(BCMSDIO) || defined(BCMDBUS)
if (!ret) {
if (dhd_dev_init_ioctl(dev) < 0) {
ret = -EFAULT;
goto err;
}
}
#endif /* !BCMPCIE */
#ifdef IAPSTA_PREINIT
conf = dhd_get_conf(dev);
if (conf) {
wl_android_ext_priv_cmd(dev, conf->iapsta_init, 0, &bytes_written);
wl_android_ext_priv_cmd(dev, conf->iapsta_config, 0, &bytes_written);
wl_android_ext_priv_cmd(dev, conf->iapsta_enable, 0, &bytes_written);
}
#endif
#endif /* BCMSDIO || BCMDBUS */
g_wifi_on = TRUE;
}
@ -1621,15 +1616,17 @@ int wl_android_wifi_on(struct net_device *dev)
dhd_net_if_unlock(dev);
return ret;
#ifdef BCMSDIO
#if defined(BCMSDIO) || defined(BCMDBUS)
err:
dhd_net_bus_devreset(dev, TRUE);
#ifdef BCMSDIO
dhd_net_bus_suspend(dev);
#endif /* BCMSDIO */
dhd_net_wifi_platform_set_power(dev, FALSE, WIFI_TURNOFF_DELAY);
printf("%s: Failed\n", __FUNCTION__);
dhd_net_if_unlock(dev);
return ret;
#endif
#endif /* BCMSDIO || BCMDBUS */
}
int wl_android_wifi_off(struct net_device *dev, bool on_failure)
@ -1652,12 +1649,12 @@ int wl_android_wifi_off(struct net_device *dev, bool on_failure)
dhd_net_if_lock(dev);
printf("%s in 2: g_wifi_on=%d, on_failure=%d\n", __FUNCTION__, g_wifi_on, on_failure);
if (g_wifi_on || on_failure) {
#if defined(BCMSDIO) || defined(BCMPCIE)
#if defined(BCMSDIO) || defined(BCMPCIE) || defined(BCMDBUS)
ret = dhd_net_bus_devreset(dev, TRUE);
#if defined(BCMSDIO)
dhd_net_bus_suspend(dev);
#endif /* BCMSDIO */
#endif /* BCMSDIO || BCMPCIE */
#endif /* BCMSDIO || BCMPCIE || BCMDBUS */
dhd_net_wifi_platform_set_power(dev, FALSE, WIFI_TURNOFF_DELAY);
g_wifi_on = FALSE;
}
@ -2497,6 +2494,7 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str,
uint32 band = WLC_BAND_2G;
uint32 buf_size;
char *pos = command;
int band_new, band_cur;
if (cmd_str) {
ANDROID_INFO(("Command: %s len:%d \n", cmd_str, (int)strlen(cmd_str)));
@ -2516,20 +2514,22 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str,
(channel == APCS_BAND_2G_LEGACY2)) {
band = WLC_BAND_2G;
} else {
ANDROID_ERROR(("Invalid argument\n"));
ANDROID_ERROR(("%s: Invalid argument\n", __FUNCTION__));
return -EINVAL;
}
}
} else {
/* If no argument is provided, default to 2G */
ANDROID_ERROR(("No argument given default to 2.4G scan\n"));
ANDROID_ERROR(("%s: No argument given default to 2.4G scan\n", __FUNCTION__));
band = WLC_BAND_2G;
}
ANDROID_INFO(("HAPD_AUTO_CHANNEL = %d, band=%d \n", channel, band));
ANDROID_INFO(("%s : HAPD_AUTO_CHANNEL = %d, band=%d \n", __FUNCTION__, channel, band));
ret = wldev_ioctl_set(dev, WLC_GET_BAND, &band_cur, sizeof(band_cur));
if ((ret =
wldev_ioctl_get(dev, WLC_GET_SPECT_MANAGMENT, &spect, sizeof(spect))) < 0) {
ANDROID_ERROR(("ACS: error getting the spect\n"));
ANDROID_ERROR(("%s: ACS: error getting the spect\n", __FUNCTION__));
goto done;
}
@ -2551,15 +2551,19 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str,
reqbuf = kzalloc(CHANSPEC_BUF_SIZE, GFP_KERNEL);
if (reqbuf == NULL) {
ANDROID_ERROR(("failed to allocate chanspec buffer\n"));
ANDROID_ERROR(("%s: failed to allocate chanspec buffer\n", __FUNCTION__));
return -ENOMEM;
}
if (band == WLC_BAND_AUTO) {
ANDROID_INFO(("ACS full channel scan \n"));
ANDROID_INFO(("%s: ACS full channel scan \n", __func__));
reqbuf[0] = htod32(0);
} else if (band == WLC_BAND_5G) {
ANDROID_INFO(("ACS 5G band scan \n"));
band_new = band_cur==WLC_BAND_2G ? band_cur : WLC_BAND_5G;
ret = wldev_ioctl_set(dev, WLC_SET_BAND, &band_new, sizeof(band_new));
if (ret < 0)
WL_ERR(("WLC_SET_BAND error %d\n", ret));
ANDROID_INFO(("%s: ACS 5G band scan \n", __func__));
if ((ret = wl_cfg80211_get_chanspecs_5g(dev, reqbuf, CHANSPEC_BUF_SIZE)) < 0) {
ANDROID_ERROR(("ACS 5g chanspec retreival failed! \n"));
goto done;
@ -2569,7 +2573,7 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str,
* If channel argument is not provided/ argument 20 is provided,
* Restrict channel to 2GHz, 20MHz BW, No SB
*/
ANDROID_INFO(("ACS 2G band scan \n"));
ANDROID_INFO(("%s: ACS 2G band scan \n", __func__));
if ((ret = wl_cfg80211_get_chanspecs_2g(dev, reqbuf, CHANSPEC_BUF_SIZE)) < 0) {
ANDROID_ERROR(("ACS 2g chanspec retreival failed! \n"));
goto done;
@ -2579,11 +2583,12 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str,
goto done2;
}
buf_size = (band == WLC_BAND_AUTO) ? sizeof(int) : CHANSPEC_BUF_SIZE;
buf_size = CHANSPEC_BUF_SIZE;
ret = wldev_ioctl_set(dev, WLC_START_CHANNEL_SEL, (void *)reqbuf,
buf_size);
if (ret < 0) {
ANDROID_ERROR(("can't start auto channel scan, err = %d\n", ret));
ANDROID_ERROR(("%s: can't start auto channel scan, err = %d\n",
__FUNCTION__, ret));
channel = 0;
goto done;
}
@ -2609,6 +2614,18 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str,
chosen = dtoh32(chosen);
}
if ((ret == 0) && (dtoh32(chosen) != 0)) {
uint chip;
chip = dhd_conf_get_chip(dhd_get_pub(dev));
if (chip != BCM43143_CHIP_ID) {
u32 chanspec = 0;
chanspec = wl_chspec_driver_to_host(chosen);
ANDROID_INFO(("%s: selected chanspec = 0x%x\n", __FUNCTION__, chanspec));
chosen = wf_chspec_ctlchan(chanspec);
ANDROID_INFO(("%s: selected chosen = 0x%x\n", __FUNCTION__, chosen));
}
}
if (chosen) {
int chosen_band;
int apcs_band;
@ -2623,12 +2640,15 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str,
#endif /* D11AC_IOTYPES */
apcs_band = (band == WLC_BAND_AUTO) ? WLC_BAND_2G : band;
chosen_band = (channel <= CH_MAX_2G_CHANNEL) ? WLC_BAND_2G : WLC_BAND_5G;
if (apcs_band == chosen_band) {
if (band == WLC_BAND_AUTO) {
printf("%s: selected channel = %d\n", __FUNCTION__, channel);
break;
} else if (apcs_band == chosen_band) {
printf("%s: selected channel = %d\n", __FUNCTION__, channel);
break;
}
}
ANDROID_INFO(("%d tried, ret = %d, chosen = 0x%x\n",
ANDROID_INFO(("%s: %d tried, ret = %d, chosen = 0x%x\n", __FUNCTION__,
(APCS_MAX_RETRY - retry), ret, chosen));
OSL_SLEEP(250);
}
@ -2641,12 +2661,16 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str,
} else {
channel = APCS_DEFAULT_2G_CH;
}
ANDROID_ERROR(("ACS failed. Fall back to default channel (%d) \n", channel));
ANDROID_ERROR(("%s: ACS failed."
" Fall back to default channel (%d) \n", __FUNCTION__, channel));
}
done2:
ret = wldev_ioctl_set(dev, WLC_SET_BAND, &band_cur, sizeof(band_cur));
if (ret < 0)
WL_ERR(("WLC_SET_BAND error %d\n", ret));
if (spect > 0) {
if ((ret = wl_cfg80211_set_spect(dev, spect) < 0)) {
ANDROID_ERROR(("ACS: error while setting spect\n"));
ANDROID_ERROR(("%s: ACS: error while setting spect\n", __FUNCTION__));
}
}
@ -2660,7 +2684,7 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str,
else
pos += snprintf(pos, total_len, "5g=");
pos += snprintf(pos, total_len, "%d", channel);
ANDROID_INFO(("command result is %s \n", command));
ANDROID_INFO(("%s: command result is %s \n", __FUNCTION__, command));
return strlen(command);
} else {
return ret;
@ -3754,8 +3778,7 @@ wl_cfg80211_p2plo_offload(struct net_device *dev, char *cmd, char* buf, int len)
}
#endif /* P2P_LISTEN_OFFLOADING */
#ifdef WL_CFG80211
#ifdef BCM4359_CHIP
#if defined(BCM4359_CHIP) && defined(WL_CFG80211)
int
wl_android_murx_bfe_cap(struct net_device *dev, int val)
{
@ -3797,7 +3820,6 @@ wl_android_murx_bfe_cap(struct net_device *dev, int val)
return err;
}
#endif /* BCM4359_CHIP */
#endif
#ifdef SUPPORT_AP_HIGHER_BEACONRATE
int
@ -4203,6 +4225,40 @@ wl_android_make_hang_with_reason(struct net_device *dev, const char *string_num)
}
#endif /* DHD_HANG_SEND_UP_TEST */
#ifdef WL_CFG80211
#ifdef WLMESH
static int
wl_android_set_rsdb_mode(struct net_device *dev, char *command, int total_len)
{
int ret;
wl_config_t rsdb_mode_cfg = {-1, 0};
char smbuf[WLC_IOCTL_SMLEN];
s32 val = 1;
if (sscanf(command, "%*s %d", &rsdb_mode_cfg.config) != 1) {
DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
return -1;
}
DHD_INFO(("%s : RSDB_MODE = %d\n", __FUNCTION__, rsdb_mode_cfg.config));
ret = wldev_ioctl_set(dev, WLC_DOWN, &val, sizeof(s32));
if (ret < 0)
DHD_ERROR(("WLC_DOWN error %d\n", ret));
ret = wldev_iovar_setbuf(dev, "rsdb_mode", &rsdb_mode_cfg, sizeof(rsdb_mode_cfg),
smbuf, sizeof(smbuf), NULL);
if (ret < 0)
DHD_ERROR(("%s : set rsdb_mode error=%d\n", __FUNCTION__, ret));
ret = wldev_ioctl_set(dev, WLC_UP, &val, sizeof(s32));
if (ret < 0)
DHD_ERROR(("WLC_UP error %d\n", ret));
return ret;
}
#endif /* WLMESH */
#endif /* WL_CFG80211 */
#ifdef SUPPORT_LQCM
static int
wl_android_lqcm_enable(struct net_device *net, int lqcm_enable)
@ -4813,7 +4869,7 @@ wl_handle_private_cmd(struct net_device *net, char *command, u32 cmd_len)
bytes_written = BCME_DISABLED;
#else /* DISABLE_SETBAND */
uint band = *(command + strlen(CMD_SETBAND) + 1) - '0';
if (dhd_conf_get_band(dhd_get_pub(net)) != WLC_BAND_AUTO) {
if (dhd_conf_get_band(dhd_get_pub(net)) >= WLC_BAND_AUTO) {
printf("%s: Band is fixed in config.txt\n", __FUNCTION__);
} else
bytes_written = wl_cfg80211_set_if_band(net, band);
@ -4824,6 +4880,14 @@ wl_handle_private_cmd(struct net_device *net, char *command, u32 cmd_len)
bytes_written = wl_android_get_band(net, command, priv_cmd.total_len);
}
#ifdef WL_CFG80211
else if (strnicmp(command, CMD_SET_CSA, strlen(CMD_SET_CSA)) == 0) {
bytes_written = wl_android_set_csa(net, command, priv_cmd.total_len);
} else if (strnicmp(command, CMD_80211_MODE, strlen(CMD_80211_MODE)) == 0) {
bytes_written = wl_android_get_80211_mode(net, command, priv_cmd.total_len);
} else if (strnicmp(command, CMD_CHANSPEC, strlen(CMD_CHANSPEC)) == 0) {
bytes_written = wl_android_get_chanspec(net, command, priv_cmd.total_len);
}
#endif /* WL_CFG80211 */
/* CUSTOMER_SET_COUNTRY feature is define for only GGSM model */
else if (strnicmp(command, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) {
/*
@ -4858,14 +4922,6 @@ wl_handle_private_cmd(struct net_device *net, char *command, u32 cmd_len)
#endif /* FCC_PWR_LIMIT_2G */
#endif /* CUSTOMER_HW4_PRIVATE_CMD */
}
else if (strnicmp(command, CMD_SET_CSA, strlen(CMD_SET_CSA)) == 0) {
bytes_written = wl_android_set_csa(net, command, priv_cmd.total_len);
} else if (strnicmp(command, CMD_80211_MODE, strlen(CMD_80211_MODE)) == 0) {
bytes_written = wl_android_get_80211_mode(net, command, priv_cmd.total_len);
} else if (strnicmp(command, CMD_CHANSPEC, strlen(CMD_CHANSPEC)) == 0) {
bytes_written = wl_android_get_chanspec(net, command, priv_cmd.total_len);
}
#endif /* WL_CFG80211 */
else if (strnicmp(command, CMD_DATARATE, strlen(CMD_DATARATE)) == 0) {
bytes_written = wl_android_get_datarate(net, command, priv_cmd.total_len);
} else if (strnicmp(command, CMD_ASSOC_CLIENTS, strlen(CMD_ASSOC_CLIENTS)) == 0) {
@ -4900,6 +4956,18 @@ wl_handle_private_cmd(struct net_device *net, char *command, u32 cmd_len)
else if (strnicmp(command, CMD_P2P_DEV_ADDR, strlen(CMD_P2P_DEV_ADDR)) == 0) {
bytes_written = wl_android_get_p2p_dev_addr(net, command, priv_cmd.total_len);
}
#ifdef WL_CFG80211
#ifdef WLMESH
else if (strnicmp(command, CMD_SAE_SET_PASSWORD, strlen(CMD_SAE_SET_PASSWORD)) == 0) {
int skip = strlen(CMD_SAE_SET_PASSWORD) + 1;
bytes_written = wl_cfg80211_set_sae_password(net, command + skip,
priv_cmd.total_len - skip);
}
else if (strnicmp(command, CMD_SET_RSDB_MODE, strlen(CMD_SET_RSDB_MODE)) == 0) {
bytes_written = wl_android_set_rsdb_mode(net, command, priv_cmd.total_len);
}
#endif
#endif /* WL_CFG80211 */
else if (strnicmp(command, CMD_P2P_SET_NOA, strlen(CMD_P2P_SET_NOA)) == 0) {
int skip = strlen(CMD_P2P_SET_NOA) + 1;
bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip,
@ -5165,17 +5233,15 @@ wl_handle_private_cmd(struct net_device *net, char *command, u32 cmd_len)
bytes_written = wl_cfg80211_get_sta_info(net, command, priv_cmd.total_len);
}
#endif /* CUSTOMER_HW4_PRIVATE_CMD */
#ifdef WL_CFG80211
else if (strnicmp(command, CMD_MURX_BFE_CAP,
strlen(CMD_MURX_BFE_CAP)) == 0) {
#ifdef BCM4359_CHIP
#if defined(BCM4359_CHIP) && defined(WL_CFG80211)
uint val = *(command + strlen(CMD_MURX_BFE_CAP) + 1) - '0';
bytes_written = wl_android_murx_bfe_cap(net, val);
#else
return BCME_UNSUPPORTED;
#endif /* BCM4359_CHIP */
}
#endif
#ifdef SUPPORT_AP_HIGHER_BEACONRATE
else if (strnicmp(command, CMD_GET_AP_BASICRATE, strlen(CMD_GET_AP_BASICRATE)) == 0) {
bytes_written = wl_android_get_ap_basicrate(net, command, priv_cmd.total_len);

View File

@ -104,9 +104,14 @@ int wl_handle_private_cmd(struct net_device *net, char *command, u32 cmd_len);
s32 wl_netlink_send_msg(int pid, int type, int seq, const void *data, size_t size);
#ifdef WL_EXT_IAPSTA
int wl_android_ext_attach_netdev(struct net_device *net, uint8 bssidx);
int wl_android_ext_dettach_netdev(void);
void wl_android_ext_iapsta_disconnect_sta(struct net_device *dev, u32 channel);
int wl_ext_iapsta_attach_netdev(struct net_device *net, uint8 bssidx);
int wl_ext_iapsta_attach_name(struct net_device *net, uint8 bssidx);
int wl_ext_iapsta_dettach_netdev(void);
u32 wl_ext_iapsta_disconnect_sta(struct net_device *dev, u32 channel);
int wl_ext_iapsta_alive_preinit(struct net_device *dev);
int wl_ext_iapsta_alive_postinit(struct net_device *dev);
int wl_ext_iapsta_event(struct net_device *dev, wl_event_msg_t *e, void* data);
extern int op_mode;
#endif
int wl_android_ext_priv_cmd(struct net_device *net, char *command, int total_len,
int *bytes_written);
@ -114,76 +119,6 @@ int wl_android_ext_priv_cmd(struct net_device *net, char *command, int total_len
#define strnicmp(str1, str2, len) strncasecmp((str1), (str2), (len))
#endif
typedef enum IF_STATE {
IF_STATE_INIT = 1,
IF_STATE_DISALBE,
IF_STATE_ENABLE
} if_state_t;
typedef enum APSTAMODE {
ISTAONLY_MODE = 1,
IAPONLY_MODE,
IAPSTA_MODE,
IDUALAP_MODE,
IGOSTA_MODE,
IGCSTA_MODE
} apstamode_t;
typedef enum IFMODE {
ISTA_MODE = 1,
IAP_MODE
} ifmode_t;
typedef enum BGNMODE {
IEEE80211B = 1,
IEEE80211G,
IEEE80211BG,
IEEE80211BGN,
IEEE80211BGNAC
} bgnmode_t;
typedef enum AUTHMODE {
AUTH_OPEN,
AUTH_SHARED,
AUTH_WPAPSK,
AUTH_WPA2PSK,
AUTH_WPAWPA2PSK
} authmode_t;
typedef enum ENCMODE {
ENC_NONE,
ENC_WEP,
ENC_TKIP,
ENC_AES,
ENC_TKIPAES
} encmode_t;
/* i/f query */
typedef struct wl_if_info {
struct net_device *dev;
if_state_t ifstate;
ifmode_t ifmode;
uint bssidx;
char ifname[IFNAMSIZ+1];
char ssid[DOT11_MAX_SSID_LEN];
struct ether_addr bssid;
bgnmode_t bgnmode;
int hidden;
int maxassoc;
uint16 channel;
authmode_t amode;
encmode_t emode;
char key[100];
} wl_apsta_if_t;
typedef struct wl_apsta_params {
struct wl_if_info pif; // primary device
struct wl_if_info vif; // virtual device
int ioctl_ver;
bool init;
apstamode_t apstamode;
} wl_apsta_params_t;
/* hostap mac mode */
#define MACLIST_MODE_DISABLED 0
#define MACLIST_MODE_DENY 1
@ -224,6 +159,10 @@ int wl_android_set_ap_mac_list(struct net_device *dev, int macmode, struct macli
#define REPEATED_SCAN_RESULT_CNT 1
#endif
#if defined(RSSIAVG) || defined(RSSIOFFSET)
extern int g_wifi_on;
#endif
#if defined(RSSIAVG)
#define RSSIAVG_LEN (4*REPEATED_SCAN_RESULT_CNT)
#define RSSICACHE_TIMEOUT 15
@ -286,4 +225,12 @@ void wl_update_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl,
wl_scan_results_t *ss_list);
void wl_release_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl);
#endif
int wl_ext_get_best_channel(struct net_device *net,
#if defined(BSSCACHE)
wl_bss_cache_ctrl_t *bss_cache_ctrl,
#else
struct wl_scan_results *bss_list,
#endif
int *best_2g_ch, int *best_5g_ch
);
#endif /* _wl_android_ */

View File

@ -45,6 +45,7 @@
#include <dngl_stats.h>
#include <dhd.h>
#include <wl_cfgp2p.h>
#include <wl_android.h>
struct wl_conf;
struct wl_iface;
struct bcm_cfg80211;
@ -205,6 +206,11 @@ do { \
#define IEEE80211_BAND_5GHZ NL80211_BAND_5GHZ
#define IEEE80211_NUM_BANDS NUM_NL80211_BANDS
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
#ifdef WLMESH
#undef WLMESH
#endif
#endif
#define WL_SCAN_RETRY_MAX 3
#define WL_NUM_PMKIDS_MAX MAXPMKID
@ -339,7 +345,10 @@ enum wl_status {
enum wl_mode {
WL_MODE_BSS,
WL_MODE_IBSS,
WL_MODE_AP
WL_MODE_AP,
#ifdef WLMESH
WL_MODE_MESH
#endif
};
/* driver profile list */
@ -735,7 +744,7 @@ struct bcm_cfg80211 {
bool pwr_save;
bool roam_on; /* on/off switch for self-roaming */
bool scan_tried; /* indicates if first scan attempted */
#if defined(BCMSDIO) || defined(BCMPCIE)
#if defined(BCMSDIO) || defined(BCMDBUS)
bool wlfc_on;
#endif
bool vsdb_mode;
@ -845,9 +854,23 @@ struct bcm_cfg80211 {
#ifdef STAT_REPORT
void *stat_report_info;
#endif
#ifdef WLMESH
char sae_password[SAE_MAX_PASSWD_LEN];
uint sae_password_len;
#endif /* WLMESH */
#if defined(RSSIAVG)
wl_rssi_cache_ctrl_t g_rssi_cache_ctrl;
wl_rssi_cache_ctrl_t g_connected_rssi_cache_ctrl;
#endif
#if defined(BSSCACHE)
wl_bss_cache_ctrl_t g_bss_cache_ctrl;
#endif
int p2p_disconnected; // terence 20130703: Fix for wrong group_capab (timing issue)
struct ether_addr disconnected_bssid;
int autochannel;
int best_2g_ch;
int best_5g_ch;
};
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
@ -1462,6 +1485,9 @@ extern s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len
extern s32 wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len);
extern s32 wl_cfg80211_set_p2p_ecsa(struct net_device *net, char* buf, int len);
extern s32 wl_cfg80211_increase_p2p_bw(struct net_device *net, char* buf, int len);
#ifdef WLMESH
extern s32 wl_cfg80211_set_sae_password(struct net_device *net, char* buf, int len);
#endif
#ifdef WL11ULB
extern s32 wl_cfg80211_set_ulb_mode(struct net_device *dev, int mode);
extern s32 wl_cfg80211_set_ulb_bw(struct net_device *dev,
@ -1652,4 +1678,5 @@ int wl_cfg80211_iface_count(struct net_device *dev);
struct net_device* wl_get_ap_netdev(struct bcm_cfg80211 *cfg, char *ifname);
struct net_device* wl_get_netdev_by_name(struct bcm_cfg80211 *cfg, char *ifname);
int wl_cfg80211_get_vndr_ouilist(struct bcm_cfg80211 *cfg, uint8 *buf, int max_cnt);
s32 wl_cfg80211_autochannel(struct net_device *dev, char* command, int total_len);
#endif /* _wl_cfg80211_h_ */

View File

@ -294,9 +294,19 @@ wl_cfg80211_bt_setflag(struct net_device *dev, bool set)
#endif
}
static void wl_cfg80211_bt_timerfunc(ulong data)
static void wl_cfg80211_bt_timerfunc(
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
struct timer_list *t
#else
unsigned long data
#endif
)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
struct btcoex_info *bt_local = from_timer(bt_local, t, timer);
#else
struct btcoex_info *bt_local = (struct btcoex_info *)data;
#endif
WL_TRACE(("Enter\n"));
bt_local->timer_on = 0;
schedule_work(&bt_local->work);
@ -393,9 +403,13 @@ void* wl_cfg80211_btcoex_init(struct net_device *ndev)
btco_inf->ts_dhcp_ok = 0;
/* Set up timer for BT */
btco_inf->timer_ms = 10;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
timer_setup(&btco_inf->timer, wl_cfg80211_bt_timerfunc, 0);
#else
init_timer(&btco_inf->timer);
btco_inf->timer.data = (ulong)btco_inf;
btco_inf->timer.function = wl_cfg80211_bt_timerfunc;
#endif
btco_inf->dev = ndev;

View File

@ -56,6 +56,7 @@
#include <dhdioctl.h>
#include <wlioctl.h>
#include <dhd_cfg80211.h>
#include <dhd_config.h>
#if defined(BCMPCIE) && defined(DHD_FW_COREDUMP)
extern int dhd_bus_mem_dump(dhd_pub_t *dhd);
@ -333,6 +334,9 @@ wl_cfgp2p_init_priv(struct bcm_cfg80211 *cfg)
return -ENOMEM;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
cfg->p2p->cfg = cfg;
#endif
wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_PRIMARY) = bcmcfg_to_prmry_ndev(cfg);
wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_PRIMARY) = 0;
wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_DEVICE) = NULL;
@ -1385,10 +1389,21 @@ wl_cfgp2p_listen_complete(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
* so lets do it from thread context.
*/
void
wl_cfgp2p_listen_expired(unsigned long data)
wl_cfgp2p_listen_expired(
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
struct timer_list *t
#else
ulong data
#endif
)
{
wl_event_msg_t msg;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
struct p2p_info *p2p = from_timer(p2p, t, listen_timer);
struct bcm_cfg80211 *cfg = p2p->cfg;
#else
struct bcm_cfg80211 *cfg = (struct bcm_cfg80211 *) data;
#endif
struct net_device *ndev;
CFGP2P_DBG((" Enter\n"));
@ -1742,6 +1757,8 @@ wl_cfgp2p_supported(struct bcm_cfg80211 *cfg, struct net_device *ndev)
return ret;
}
}
if (cfg->pub->conf->fw_type == FW_TYPE_MESH)
p2p_supported = 0;
if (p2p_supported == 1) {
CFGP2P_INFO(("p2p is supported\n"));
} else {
@ -1750,6 +1767,7 @@ wl_cfgp2p_supported(struct bcm_cfg80211 *cfg, struct net_device *ndev)
}
return p2p_supported;
}
/* Cleanup P2P resources */
s32
wl_cfgp2p_down(struct bcm_cfg80211 *cfg)

View File

@ -71,6 +71,9 @@ struct p2p_bss {
};
struct p2p_info {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
struct bcm_cfg80211 *cfg;
#endif
bool on; /**< p2p on/off switch */
bool scan;
int16 search_state;
@ -183,6 +186,14 @@ enum wl_cfgp2p_status {
printk args; \
} \
} while (0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
#define INIT_TIMER(timer, func, duration, extra_delay) \
do { \
timer_setup(timer, func, 0); \
timer->expires = jiffies + msecs_to_jiffies(duration + extra_delay); \
add_timer(timer); \
} while (0);
#else
#define INIT_TIMER(timer, func, duration, extra_delay) \
do { \
init_timer(timer); \
@ -191,6 +202,7 @@ enum wl_cfgp2p_status {
timer->data = (unsigned long) cfg; \
add_timer(timer); \
} while (0);
#endif
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 0, 8))
#ifdef WL_SUPPORT_BACKPORTED_KPATCHES
@ -245,7 +257,13 @@ enum wl_cfgp2p_status {
#define P2P_ECSA_CNT 50
extern void
wl_cfgp2p_listen_expired(unsigned long data);
wl_cfgp2p_listen_expired(
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
struct timer_list *t
#else
ulong data
#endif
);
extern bool
wl_cfgp2p_is_pub_action(void *frame, u32 frame_len);
extern bool

View File

@ -2322,10 +2322,15 @@ static int wl_cfgvendor_lstats_get_info(struct wiphy *wiphy,
((wl_cnt_info_t *)iovar_buf)->datalen,
WL_CNT_XTLV_CNTV_LE10_UCODE, NULL,
BCM_XTLV_OPTION_ALIGN32)) == NULL) {
macstat_cnt = bcm_get_data_from_xtlv_buf(((wl_cnt_info_t *)iovar_buf)->data,
if ((macstat_cnt = bcm_get_data_from_xtlv_buf(((wl_cnt_info_t *)iovar_buf)->data,
((wl_cnt_info_t *)iovar_buf)->datalen,
WL_CNT_XTLV_GE40_UCODE_V1, NULL,
BCM_XTLV_OPTION_ALIGN32)) == NULL) {
macstat_cnt = bcm_get_data_from_xtlv_buf(((wl_cnt_info_t *)iovar_buf)->data,
((wl_cnt_info_t *)iovar_buf)->datalen,
WL_CNT_XTLV_LT40_UCODE_V1, NULL,
BCM_XTLV_OPTION_ALIGN32);
}
}
if (macstat_cnt == NULL) {

View File

@ -1,5 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 */
#if defined(WL_ESCAN)
#include <typedefs.h>
@ -29,21 +28,21 @@
#define ESCAN_ERROR(x) \
do { \
if (iw_msg_level & ESCAN_ERROR_LEVEL) { \
printf(KERN_ERR "ESCAN-ERROR) "); \
printf(KERN_ERR "ESCAN-ERROR) %s : ", __func__); \
printf x; \
} \
} while (0)
#define ESCAN_SCAN(x) \
do { \
if (iw_msg_level & ESCAN_SCAN_LEVEL) { \
printf(KERN_ERR "ESCAN-SCAN) "); \
printf(KERN_ERR "ESCAN-SCAN) %s : ", __func__); \
printf x; \
} \
} while (0)
#define ESCAN_TRACE(x) \
do { \
if (iw_msg_level & ESCAN_TRACE_LEVEL) { \
printf(KERN_ERR "ESCAN-TRACE) "); \
printf(KERN_ERR "ESCAN-TRACE) %s : ", __func__); \
printf x; \
} \
} while (0)
@ -73,15 +72,6 @@ typedef struct {
#endif /* ESCAN_BUF_OVERFLOW_MGMT */
struct wl_escan_info *g_escan = NULL;
#if defined(RSSIAVG)
static wl_rssi_cache_ctrl_t g_rssi_cache_ctrl;
static wl_rssi_cache_ctrl_t g_connected_rssi_cache_ctrl;
#endif
#if defined(BSSCACHE)
static wl_bss_cache_ctrl_t g_bss_cache_ctrl;
#endif
/* Return a new chanspec given a legacy chanspec
* Returns INVCHANSPEC on error
*/
@ -416,7 +406,7 @@ static s32 wl_escan_event_handler(void *data)
}
void
wl_escan_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
wl_escan_event(struct net_device *dev, const wl_event_msg_t * e, void *data)
{
u32 event_type = ntoh32(e->event_type);
struct wl_escan_info *escan = g_escan;
@ -443,7 +433,7 @@ wl_escan_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
}
DHD_EVENT_WAKE_LOCK(escan->pub);
if (likely(!wl_enq_event(escan, ndev, event_type, e, data))) {
if (likely(!wl_enq_event(escan, dev, event_type, e, data))) {
wl_wakeup_event(escan);
} else {
DHD_EVENT_WAKE_UNLOCK(escan->pub);
@ -462,34 +452,39 @@ static s32 wl_escan_inform_bss(struct wl_escan_info *escan)
/* Delete disconnected cache */
#if defined(BSSCACHE)
wl_delete_disconnected_bss_cache(&g_bss_cache_ctrl, (u8*)&escan->disconnected_bssid);
wl_delete_disconnected_bss_cache(&escan->g_bss_cache_ctrl, (u8*)&escan->disconnected_bssid);
#if defined(RSSIAVG)
wl_delete_disconnected_rssi_cache(&g_rssi_cache_ctrl, (u8*)&escan->disconnected_bssid);
wl_delete_disconnected_rssi_cache(&escan->g_rssi_cache_ctrl, (u8*)&escan->disconnected_bssid);
#endif
#endif
/* Update cache */
#if defined(RSSIAVG)
wl_update_rssi_cache(&g_rssi_cache_ctrl, bss_list);
wl_update_rssi_cache(&escan->g_rssi_cache_ctrl, bss_list);
if (!in_atomic())
wl_update_connected_rssi_cache(escan->dev, &g_rssi_cache_ctrl, &rssi);
wl_update_connected_rssi_cache(escan->dev, &escan->g_rssi_cache_ctrl, &rssi);
#endif
#if defined(BSSCACHE)
wl_update_bss_cache(&g_bss_cache_ctrl,
wl_update_bss_cache(&escan->g_bss_cache_ctrl,
#if defined(RSSIAVG)
&g_rssi_cache_ctrl,
&escan->g_rssi_cache_ctrl,
#endif
bss_list);
#endif
/* delete dirty cache */
#if defined(RSSIAVG)
wl_delete_dirty_rssi_cache(&g_rssi_cache_ctrl);
wl_reset_rssi_cache(&g_rssi_cache_ctrl);
wl_delete_dirty_rssi_cache(&escan->g_rssi_cache_ctrl);
wl_reset_rssi_cache(&escan->g_rssi_cache_ctrl);
#endif
#if defined(BSSCACHE)
wl_delete_dirty_bss_cache(&g_bss_cache_ctrl);
wl_reset_bss_cache(&g_bss_cache_ctrl);
wl_delete_dirty_bss_cache(&escan->g_bss_cache_ctrl);
wl_reset_bss_cache(&escan->g_bss_cache_ctrl);
if (escan->autochannel)
wl_ext_get_best_channel(escan->dev, &escan->g_bss_cache_ctrl, &escan->best_2g_ch, &escan->best_5g_ch);
#else
if (escan->autochannel)
wl_ext_get_best_channel(escan->dev, bss_list, &escan->best_2g_ch, &escan->best_5g_ch);
#endif
ESCAN_TRACE(("scanned AP count (%d)\n", bss_list->count));
@ -849,20 +844,21 @@ static s32 wl_escan_handler(struct wl_escan_info *escan,
}
else if (status == WLC_E_STATUS_SUCCESS) {
escan->escan_state = ESCAN_STATE_IDLE;
ESCAN_TRACE(("ESCAN COMPLETED\n"));
escan->bss_list = wl_escan_get_buf(escan);
ESCAN_TRACE(("SCAN COMPLETED: scanned AP count=%d\n",
escan->bss_list->count));
wl_escan_inform_bss(escan);
wl_notify_escan_complete(escan, false);
ESCAN_TRACE(("ESCAN COMPLETED\n"));
escan->bss_list = wl_escan_get_buf(escan);
ESCAN_TRACE(("SCAN COMPLETED: scanned AP count=%d\n",
escan->bss_list->count));
wl_escan_inform_bss(escan);
wl_notify_escan_complete(escan, false);
} else if ((status == WLC_E_STATUS_ABORT) || (status == WLC_E_STATUS_NEWSCAN) ||
(status == WLC_E_STATUS_11HQUIET) || (status == WLC_E_STATUS_CS_ABORT) ||
(status == WLC_E_STATUS_NEWASSOC)) {
/* Handle all cases of scan abort */
escan->escan_state = ESCAN_STATE_IDLE;
ESCAN_TRACE(("ESCAN ABORT reason: %d\n", status));
escan->bss_list = wl_escan_get_buf(escan);
ESCAN_TRACE(("SCAN ABORT: scanned AP count=%d\n",
escan->bss_list->count));
wl_escan_inform_bss(escan);
wl_notify_escan_complete(escan, false);
} else if (status == WLC_E_STATUS_TIMEOUT) {
@ -871,6 +867,7 @@ static s32 wl_escan_handler(struct wl_escan_info *escan,
if (e->reason == 0xFFFFFFFF) {
wl_notify_escan_complete(escan, true);
}
escan->escan_state = ESCAN_STATE_IDLE;
} else {
ESCAN_ERROR(("unexpected Escan Event %d : abort\n", status));
escan->escan_state = ESCAN_STATE_IDLE;
@ -983,9 +980,8 @@ wl_escan_prep(struct wl_escan_info *escan, wl_uint32_list_t *list,
return err;
}
static int wl_escan_reset(void) {
struct wl_escan_info *escan = g_escan;
static int wl_escan_reset(struct wl_escan_info *escan)
{
if (timer_pending(&escan->scan_timeout))
del_timer_sync(&escan->scan_timeout);
escan->escan_state = ESCAN_STATE_IDLE;
@ -993,10 +989,20 @@ static int wl_escan_reset(void) {
return 0;
}
static void wl_escan_timeout(unsigned long data)
static void wl_escan_timeout(
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
struct timer_list *t
#else
unsigned long data
#endif
)
{
wl_event_msg_t msg;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
struct wl_escan_info *escan = from_timer(escan, t, scan_timeout);
#else
struct wl_escan_info *escan = (struct wl_escan_info *)data;
#endif
struct wl_scan_results *bss_list;
struct wl_bss_info *bi = NULL;
s32 i;
@ -1047,7 +1053,7 @@ wl_escan_set_scan(
wl_escan_params_t *params = NULL;
scb_val_t scbval;
static int cnt = 0;
struct wl_escan_info *escan = NULL;
struct wl_escan_info *escan = g_escan;
wlc_ssid_t ssid;
u32 n_channels = 0;
wl_uint32_list_t *list;
@ -1056,9 +1062,8 @@ wl_escan_set_scan(
ESCAN_TRACE(("Enter \n"));
escan = g_escan;
if (!escan) {
ESCAN_ERROR(("device is not ready\n")); \
ESCAN_ERROR(("device is not ready\n"));
return -EIO;
}
mutex_lock(&escan->usr_sync);
@ -1145,7 +1150,7 @@ wl_escan_set_scan(
ESCAN_TRACE(("Escan not permitted at this time (%d)\n", err));
else
ESCAN_ERROR(("Escan set error (%d)\n", err));
wl_escan_reset();
wl_escan_reset(escan);
}
kfree(params);
@ -1206,10 +1211,15 @@ wl_escan_get_scan(
err = -EAGAIN;
goto exit;
}
if (!escan->bss_list) {
ESCAN_ERROR(("%s: scan not ready\n", dev->name));
err = -EAGAIN;
goto exit;
}
#if defined(BSSCACHE)
bss_list = &g_bss_cache_ctrl.m_cache_head->results;
node = g_bss_cache_ctrl.m_cache_head;
bss_list = &escan->g_bss_cache_ctrl.m_cache_head->results;
node = escan->g_bss_cache_ctrl.m_cache_head;
for (i=0; node && i<IW_MAX_AP; i++)
#else
bss_list = escan->bss_list;
@ -1228,7 +1238,7 @@ wl_escan_get_scan(
}
#if defined(RSSIAVG)
rssi = wl_get_avg_rssi(&g_rssi_cache_ctrl, &bi->BSSID);
rssi = wl_get_avg_rssi(&escan->g_rssi_cache_ctrl, &bi->BSSID);
if (rssi == RSSI_MINVAL)
rssi = MIN(dtoh16(bi->RSSI), RSSI_MAXVAL);
#else
@ -1236,8 +1246,8 @@ wl_escan_get_scan(
rssi = MIN(dtoh16(bi->RSSI), RSSI_MAXVAL);
#endif
channel = wf_chspec_ctlchan(wl_chspec_driver_to_host(escan->ioctl_ver, bi->chanspec));
ESCAN_SCAN(("%s: BSSID="MACSTR", channel=%d, RSSI=%d, SSID=\"%s\"\n",
__FUNCTION__, MAC2STR(bi->BSSID.octet), channel, rssi, bi->SSID));
ESCAN_SCAN(("BSSID="MACSTR", channel=%d, RSSI=%d, SSID=\"%s\"\n",
MAC2STR(bi->BSSID.octet), channel, rssi, bi->SSID));
/* First entry must be the BSSID */
iwe.cmd = SIOCGIWAP;
@ -1323,6 +1333,27 @@ wl_escan_get_scan(
return err;
}
s32 wl_escan_autochannel(struct net_device *dev, char* command, int total_len)
{
struct wl_escan_info *escan = g_escan;
int ret = 0;
int bytes_written = -1;
sscanf(command, "%*s %d", &escan->autochannel);
if (escan->autochannel == 0) {
escan->best_2g_ch = 0;
escan->best_5g_ch = 0;
} else if (escan->autochannel == 2) {
bytes_written = snprintf(command, total_len, "2g=%d 5g=%d",
escan->best_2g_ch, escan->best_5g_ch);
ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
ret = bytes_written;
}
return ret;
}
static s32 wl_create_event_handler(struct wl_escan_info *escan)
{
int ret = 0;
@ -1343,42 +1374,44 @@ static void wl_destroy_event_handler(struct wl_escan_info *escan)
PROC_STOP(&escan->event_tsk);
}
static void wl_escan_deinit(void)
static void wl_escan_deinit(struct wl_escan_info *escan)
{
struct wl_escan_info *escan = g_escan;
printf("%s: Enter\n", __FUNCTION__);
if (!escan) {
ESCAN_ERROR(("device is not ready\n")); \
ESCAN_ERROR(("device is not ready\n"));
return;
}
wl_destroy_event_handler(escan);
wl_flush_eq(escan);
del_timer_sync(&escan->scan_timeout);
escan->escan_state = ESCAN_STATE_IDLE;
#if defined(RSSIAVG)
wl_free_rssi_cache(&g_rssi_cache_ctrl);
wl_free_rssi_cache(&escan->g_rssi_cache_ctrl);
#endif
#if defined(BSSCACHE)
wl_free_bss_cache(&g_bss_cache_ctrl);
wl_free_bss_cache(&escan->g_bss_cache_ctrl);
#endif
}
static s32 wl_escan_init(void)
static s32 wl_escan_init(struct wl_escan_info *escan)
{
struct wl_escan_info *escan = g_escan;
int err = 0;
printf("%s: Enter\n", __FUNCTION__);
if (!escan) {
ESCAN_ERROR(("device is not ready\n")); \
ESCAN_ERROR(("device is not ready\n"));
return -EIO;
}
/* Init scan_timeout timer */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
timer_setup(&escan->scan_timeout, wl_escan_timeout, 0);
#else
init_timer(&escan->scan_timeout);
escan->scan_timeout.data = (unsigned long) escan;
escan->scan_timeout.function = wl_escan_timeout;
#endif
if (wl_create_event_handler(escan)) {
err = -ENOMEM;
@ -1393,7 +1426,7 @@ static s32 wl_escan_init(void)
return 0;
err:
wl_escan_deinit();
wl_escan_deinit(escan);
return err;
}
@ -1404,11 +1437,11 @@ void wl_escan_detach(dhd_pub_t *dhdp)
printf("%s: Enter\n", __FUNCTION__);
if (!escan) {
ESCAN_ERROR(("device is not ready\n")); \
ESCAN_ERROR(("device is not ready\n"));
return;
}
wl_escan_deinit();
wl_escan_deinit(escan);
if (escan->escan_ioctl_buf) {
kfree(escan->escan_ioctl_buf);
@ -1430,10 +1463,10 @@ wl_escan_attach(struct net_device *dev, dhd_pub_t *dhdp)
escan = (wl_escan_info_t *)DHD_OS_PREALLOC(dhdp, DHD_PREALLOC_WL_ESCAN_INFO, sizeof(struct wl_escan_info));
if (!escan)
return -ENOMEM;
g_escan = escan;
memset(escan, 0, sizeof(struct wl_escan_info));
/* we only care about main interface so save a global here */
g_escan = escan;
escan->dev = dev;
escan->pub = dhdp;
escan->escan_state = ESCAN_STATE_IDLE;
@ -1444,9 +1477,7 @@ wl_escan_attach(struct net_device *dev, dhd_pub_t *dhdp)
goto err ;
}
wl_init_eq(escan);
#ifdef WL_ESCAN
wl_escan_init();
#endif
wl_escan_init(escan);
return 0;
err:

View File

@ -1,5 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _wl_escan_
#define _wl_escan_
@ -57,9 +56,19 @@ typedef struct wl_escan_info {
tsk_ctl_t event_tsk; /* task of main event handler thread */
ESCAN_EVENT_HANDLER evt_handler[WLC_E_LAST];
struct mutex usr_sync; /* maily for up/down synchronization */
int autochannel;
int best_2g_ch;
int best_5g_ch;
#if defined(RSSIAVG)
wl_rssi_cache_ctrl_t g_rssi_cache_ctrl;
wl_rssi_cache_ctrl_t g_connected_rssi_cache_ctrl;
#endif
#if defined(BSSCACHE)
wl_bss_cache_ctrl_t g_bss_cache_ctrl;
#endif
} wl_escan_info_t;
void wl_escan_event(struct net_device *ndev, const wl_event_msg_t * e, void *data);
void wl_escan_event(struct net_device *dev, const wl_event_msg_t * e, void *data);
int wl_escan_set_scan(
struct net_device *dev,
@ -69,6 +78,7 @@ int wl_escan_set_scan(
);
int wl_escan_get_scan(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra);
s32 wl_escan_autochannel(struct net_device *dev, char* command, int total_len);
int wl_escan_attach(struct net_device *dev, dhd_pub_t *dhdp);
void wl_escan_detach(dhd_pub_t *dhdp);

View File

@ -627,16 +627,18 @@ wl_iw_get_freq(
char *extra
)
{
channel_info_t ci;
int error;
u32 chanspec = 0;
int ctl_chan;
WL_TRACE(("%s: SIOCGIWFREQ\n", dev->name));
if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci))))
if ((error = dev_wlc_intvar_get(dev, "chanspec", &chanspec)))
return error;
ctl_chan = wf_chspec_ctlchan(chanspec);
/* Return radio channel in channel form */
fwrq->m = dtoh32(ci.hw_channel);
fwrq->m = ctl_chan;
fwrq->e = dtoh32(0);
return 0;
}
@ -1779,15 +1781,14 @@ wl_iw_get_essid(
/* Max SSID length check */
if (ssid.SSID_len > IW_ESSID_MAX_SIZE) {
ssid.SSID_len = IW_ESSID_MAX_SIZE;
/* Get the current SSID */
memcpy(extra, ssid.SSID, ssid.SSID_len);
/* NULL terminating as length of extra buffer is IW_ESSID_MAX_SIZE ie 32 */
extra[IW_ESSID_MAX_SIZE - 1] = '\0';
} else {
/* Get the current SSID */
memcpy(extra, ssid.SSID, ssid.SSID_len);
}
/* Get the current SSID */
memcpy(extra, ssid.SSID, ssid.SSID_len);
/* NULL terminating as length of extra buffer is IW_ESSID_MAX_SIZE ie 32 */
extra[IW_ESSID_MAX_SIZE] = '\0';
dwrq->length = ssid.SSID_len;
dwrq->flags = 1; /* active */
@ -3304,6 +3305,7 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
uint16 flags = ntoh16(e->flags);
uint32 datalen = ntoh32(e->datalen);
uint32 status = ntoh32(e->status);
uint32 reason = ntoh32(e->reason);
memset(&wrqu, 0, sizeof(wrqu));
memset(extra, 0, sizeof(extra));
@ -3333,12 +3335,12 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
cmd = SIOCGIWAP;
wrqu.data.length = strlen(extra);
if (!(flags & WLC_EVENT_MSG_LINK)) {
printf("%s: Link Down with BSSID="MACSTR"\n", __FUNCTION__,
MAC2STR((u8 *)wrqu.addr.sa_data));
printf("%s: Link Down with "MACSTR", reason=%d\n", __FUNCTION__,
MAC2STR((u8 *)wrqu.addr.sa_data), reason);
bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN);
bzero(&extra, ETHER_ADDR_LEN);
} else {
printf("%s: Link UP with BSSID="MACSTR"\n", __FUNCTION__,
printf("%s: Link UP with "MACSTR"\n", __FUNCTION__,
MAC2STR((u8 *)wrqu.addr.sa_data));
}
break;
@ -3545,15 +3547,19 @@ int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstat
#endif /* WIRELESS_EXT > 11 */
phy_noise = 0;
if ((res = dev_wlc_ioctl(dev, WLC_GET_PHY_NOISE, &phy_noise, sizeof(phy_noise))))
if ((res = dev_wlc_ioctl(dev, WLC_GET_PHY_NOISE, &phy_noise, sizeof(phy_noise)))) {
WL_ERROR(("%s: WLC_GET_PHY_NOISE error=%d\n", __FUNCTION__, res));
goto done;
}
phy_noise = dtoh32(phy_noise);
WL_TRACE(("wl_iw_get_wireless_stats phy noise=%d\n *****", phy_noise));
scb_val.val = 0;
if ((res = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t))))
memset(&scb_val, 0, sizeof(scb_val));
if ((res = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)))) {
WL_ERROR(("%s: WLC_GET_RSSI error=%d\n", __FUNCTION__, res));
goto done;
}
rssi = dtoh32(scb_val.val);
rssi = MIN(rssi, RSSI_MAXVAL);
@ -3647,9 +3653,19 @@ int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstat
#ifndef WL_ESCAN
static void
wl_iw_timerfunc(ulong data)
wl_iw_timerfunc(
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
struct timer_list *t
#else
unsigned long data
#endif
)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
iscan_info_t *iscan = from_timer(iscan, t, timer);
#else
iscan_info_t *iscan = (iscan_info_t *)data;
#endif
iscan->timer_on = 0;
if (iscan->iscan_state != ISCAN_STATE_IDLE) {
WL_TRACE(("timer trigger\n"));
@ -3887,9 +3903,13 @@ wl_iw_attach(struct net_device *dev, void * dhdp)
/* Set up the timer */
iscan->timer_ms = 2000;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
timer_setup(&iscan->timer, wl_iw_timerfunc, 0);
#else
init_timer(&iscan->timer);
iscan->timer.data = (ulong)iscan;
iscan->timer.function = wl_iw_timerfunc;
#endif
sema_init(&iscan->sysioc_sem, 0);
init_completion(&iscan->sysioc_exited);

View File

@ -34,7 +34,9 @@
#include <wldev_common.h>
#include <bcmutils.h>
#ifdef WL_CFG80211
#include <wl_cfg80211.h>
#endif
#include <dhd_config.h>
#define htod32(i) (i)
@ -478,9 +480,11 @@ int wldev_set_country(
wl_country_t cur_cspec = {{0}, 0, {0}}; /* current ccode */
scb_val_t scbval;
char smbuf[WLC_IOCTL_SMLEN];
#ifdef WL_CFG80211
struct wireless_dev *wdev = ndev_to_wdev(dev);
struct wiphy *wiphy = wdev->wiphy;
struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
#endif
if (!country_code)
return error;
@ -495,7 +499,7 @@ int wldev_set_country(
cspec.rev = revinfo;
memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ);
memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ);
error = dhd_conf_get_country_from_config(dhd_get_pub(dev), &cspec);
error = dhd_conf_map_country_list(dhd_get_pub(dev), &cspec, 0);
if (error)
dhd_get_customized_country_code(dev, (char *)&cspec.country_abbrev, &cspec);
@ -506,7 +510,11 @@ int wldev_set_country(
dhd_force_country_change(dev) ||
(strncmp(cspec.ccode, cur_cspec.ccode, WLC_CNTRY_BUF_SZ) != 0)) {
if ((user_enforced) && (wl_get_drv_status(cfg, CONNECTED, dev))) {
if ((user_enforced)
#ifdef WL_CFG80211
&& (wl_get_drv_status(cfg, CONNECTED, dev))
#endif
) {
bzero(&scbval, sizeof(scb_val_t));
error = wldev_ioctl_set(dev, WLC_DISASSOC,
&scbval, sizeof(scb_val_t));