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

Change-Id: I8c8c1f7e6b9e9b686eeebb404f5fae061bbad361
Signed-off-by: Alex Zhao <zzc@rock-chips.com>
This commit is contained in:
Alex Zhao 2018-12-13 14:26:51 +08:00 committed by Tao Huang
parent 7f34408740
commit 409cd1d0b9
25 changed files with 1995 additions and 1084 deletions

View File

@ -12,7 +12,6 @@ CONFIG_BCMDHD_PROPTXSTATUS := y
CONFIG_BCMDHD_AG := y
#CONFIG_DHD_USE_STATIC_BUF := y
CONFIG_VTS_SUPPORT := y
#CONFIG_LOGTRACE := y
CONFIG_MACH_PLATFORM := y
#CONFIG_BCMDHD_DTS := y
@ -33,6 +32,7 @@ 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 \
dhd_debug_linux.o dhd_debug.o dhd_mschdbg.o \
hnd_pktq.o hnd_pktpool.o dhd_config.o wl_android_ext.o
#BCMDHD_SDIO
@ -60,9 +60,6 @@ DHDCFLAGS += -DPCIE_FULL_DONGLE -DBCMPCIE -DCUSTOM_DPC_PRIO_SETTING=-1 \
ifneq ($(CONFIG_PCI_MSI),)
DHDCFLAGS += -DDHD_USE_MSI
endif
ifeq ($(CONFIG_DHD_USE_STATIC_BUF),y)
DHDCFLAGS += -DDHD_USE_STATIC_CTRLBUF
endif
DHDOFILES += dhd_pcie.o dhd_pcie_linux.o pcie_core.o dhd_flowring.o \
dhd_msgbuf.o
@ -74,10 +71,15 @@ 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))
ifneq ($(CONFIG_BCMDHD_CUSB),)
DHDCFLAGS += -DBCMUSBDEV_COMPOSITE
DHDCFLAGS :=$(filter-out -DENABLE_INSMOD_NO_FW_LOAD,$(DHDCFLAGS))
endif
DHDOFILES += dbus.o dbus_usb.o dbus_usb_linux.o dhd_cdc.o dhd_wlfc.o
endif
#PROPTXSTATUS
ifeq ($(CONFIG_BCMDHD_PROPTXSTATUS),y)
ifneq ($(CONFIG_BCMDHD_USB),)
DHDCFLAGS += -DPROP_TXSTATUS
@ -99,16 +101,9 @@ DHDCFLAGS += -DGSCAN_SUPPORT -DRTT_SUPPORT -DCUSTOM_FORCE_NODFS_FLAG \
-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

View File

View File

@ -1711,7 +1711,7 @@ sdioh_gpio_init(sdioh_info_t *sd)
uint
sdmmc_get_clock_rate(sdioh_info_t *sd)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) || (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0))
return 0;
#else
struct sdio_func *sdio_func = sd->func[0];
@ -1724,7 +1724,7 @@ sdmmc_get_clock_rate(sdioh_info_t *sd)
void
sdmmc_set_clock_rate(sdioh_info_t *sd, uint hz)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) || (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0))
return;
#else
struct sdio_func *sdio_func = sd->func[0];

View File

@ -1443,7 +1443,7 @@ dbus_attach(osl_t *osh, int rxsize, int nrxq, int ntxq, dhd_pub_t *pub,
dhd_bus = MALLOC(osh, sizeof(dhd_bus_t));
if (dhd_bus == NULL) {
DBUSERR(("%s: malloc failed %d\n", __FUNCTION__, sizeof(dhd_bus_t)));
DBUSERR(("%s: malloc failed %zu\n", __FUNCTION__, sizeof(dhd_bus_t)));
return NULL;
}
@ -2767,6 +2767,7 @@ dhd_dbus_probe_cb(void *arg, const char *desc, uint32 bustype,
}
} else {
pub = g_pub;
osh = pub->osh;
}
if (pub->bus) {

View File

@ -1036,13 +1036,23 @@ typedef struct dhd_pub {
#if defined(STAT_REPORT)
void *stat_report_info;
#endif
char *clm_path; /* module_param: path to clm vars file */
char *conf_path; /* module_param: path to config vars file */
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 */
#if defined(WL_WIRELESS_EXT)
#if defined(WL_ESCAN)
void *escan;
#else
void *iscan;
#endif
#endif
#ifdef WL_EXT_IAPSTA
void *iapsta_params;
#endif
} dhd_pub_t;
typedef struct {

View File

@ -4997,9 +4997,13 @@ void dhd_free_download_buffer(dhd_pub_t *dhd, void *buffer, int length)
#define EAP_PRINT(str) \
DHD_ERROR(("ETHER_TYPE_802_1X[%s] [%s]: " str "\n", \
ifname, direction ? "TX" : "RX"));
#else
#define EAP_PRINT(str)
#endif /* DHD_8021X_DUMP */
/* Parse EAPOL 4 way handshake messages */
void
dhd_dump_eapol_4way_message(char *ifname, char *dump_data, bool direction)
dhd_dump_eapol_4way_message(dhd_pub_t *dhd, char *ifname,
char *dump_data, bool direction)
{
unsigned char type;
int pair, ack, mic, kerr, req, sec, install;
@ -5008,31 +5012,43 @@ dhd_dump_eapol_4way_message(char *ifname, char *dump_data, bool direction)
type = dump_data[15];
if (type == 0) {
if ((dump_data[22] == 1) && (dump_data[18] == 1)) {
dhd->conf->eapol_status = EAPOL_STATUS_WPS_REQID;
EAP_PRINT("EAP Packet, Request, Identity");
} else if ((dump_data[22] == 1) && (dump_data[18] == 2)) {
dhd->conf->eapol_status = EAPOL_STATUS_WPS_RSPID;
EAP_PRINT("EAP Packet, Response, Identity");
} else if (dump_data[22] == 254) {
if (dump_data[30] == 1) {
dhd->conf->eapol_status = EAPOL_STATUS_WPS_WSC_START;
EAP_PRINT("EAP Packet, WSC Start");
} else if (dump_data[30] == 4) {
if (dump_data[41] == 4) {
dhd->conf->eapol_status = EAPOL_STATUS_WPS_M1;
EAP_PRINT("EAP Packet, WPS M1");
} else if (dump_data[41] == 5) {
dhd->conf->eapol_status = EAPOL_STATUS_WPS_M2;
EAP_PRINT("EAP Packet, WPS M2");
} else if (dump_data[41] == 7) {
dhd->conf->eapol_status = EAPOL_STATUS_WPS_M3;
EAP_PRINT("EAP Packet, WPS M3");
} else if (dump_data[41] == 8) {
dhd->conf->eapol_status = EAPOL_STATUS_WPS_M4;
EAP_PRINT("EAP Packet, WPS M4");
} else if (dump_data[41] == 9) {
dhd->conf->eapol_status = EAPOL_STATUS_WPS_M5;
EAP_PRINT("EAP Packet, WPS M5");
} else if (dump_data[41] == 10) {
dhd->conf->eapol_status = EAPOL_STATUS_WPS_M6;
EAP_PRINT("EAP Packet, WPS M6");
} else if (dump_data[41] == 11) {
dhd->conf->eapol_status = EAPOL_STATUS_WPS_M7;
EAP_PRINT("EAP Packet, WPS M7");
} else if (dump_data[41] == 12) {
dhd->conf->eapol_status = EAPOL_STATUS_WPS_M8;
EAP_PRINT("EAP Packet, WPS M8");
}
} else if (dump_data[30] == 5) {
dhd->conf->eapol_status = EAPOL_STATUS_WPS_DONE;
EAP_PRINT("EAP Packet, WSC Done");
}
} else {
@ -5051,12 +5067,16 @@ dhd_dump_eapol_4way_message(char *ifname, char *dump_data, bool direction)
install = 0 != (us_tmp & 0x40);
if (!sec && !mic && ack && !install && pair && !kerr && !req) {
dhd->conf->eapol_status = EAPOL_STATUS_WPA_M1;
EAP_PRINT("EAPOL Packet, 4-way handshake, M1");
} else if (pair && !install && !ack && mic && !sec && !kerr && !req) {
dhd->conf->eapol_status = EAPOL_STATUS_WPA_M2;
EAP_PRINT("EAPOL Packet, 4-way handshake, M2");
} else if (pair && ack && mic && sec && !kerr && !req) {
dhd->conf->eapol_status = EAPOL_STATUS_WPA_M3;
EAP_PRINT("EAPOL Packet, 4-way handshake, M3");
} else if (pair && !install && !ack && mic && sec && !req && !kerr) {
dhd->conf->eapol_status = EAPOL_STATUS_WPA_M4;
EAP_PRINT("EAPOL Packet, 4-way handshake, M4");
} else {
DHD_ERROR(("ETHER_TYPE_802_1X[%s] [%s]: ver %d, type %d, replay %d\n",
@ -5069,7 +5089,6 @@ dhd_dump_eapol_4way_message(char *ifname, char *dump_data, bool direction)
dump_data[14], dump_data[15], dump_data[30]));
}
}
#endif /* DHD_8021X_DUMP */
#ifdef REPORT_FATAL_TIMEOUTS
void init_dhd_timeouts(dhd_pub_t *pub)

View File

@ -61,31 +61,31 @@ const cihp_name_map_t chip_name_map [] = {
/* ChipID Chiprev AG CLM ChipName ModuleName */
#ifdef BCMSDIO
{BCM43362_CHIP_ID, 0, DONT_CARE, FALSE, "RK901a0", ""},
//{BCM43362_CHIP_ID, 1, DONT_CARE, FALSE, "RK901a2", "nvram_AP6210.txt"},
{BCM43362_CHIP_ID, 1, DONT_CARE, FALSE, "bcm40181a2", "nvram_ap6181.txt"},
//{BCM43362_CHIP_ID, 1, DONT_CARE, FALSE, "RK901a2", "AP6210"},
{BCM43362_CHIP_ID, 1, DONT_CARE, FALSE, "bcm40181a2", "ap6181"},
{BCM4330_CHIP_ID, 4, FW_TYPE_G, FALSE, "RK903b2", ""},
{BCM4330_CHIP_ID, 4, FW_TYPE_AG, FALSE, "RK903_ag", "nvram_AP6330.txt"},
{BCM43430_CHIP_ID, 0, DONT_CARE, FALSE, "bcm43438a0", "nvram_ap6212.txt"},
{BCM43430_CHIP_ID, 1, DONT_CARE, FALSE, "bcm43438a1", "nvram_ap6212a.txt"},
{BCM43430_CHIP_ID, 2, DONT_CARE, FALSE, "bcm43436b0", "nvram_ap6236.txt"},
{BCM4330_CHIP_ID, 4, FW_TYPE_AG, FALSE, "RK903_ag", "AP6330"},
{BCM43430_CHIP_ID, 0, DONT_CARE, FALSE, "bcm43438a0", "ap6212"},
{BCM43430_CHIP_ID, 1, DONT_CARE, FALSE, "bcm43438a1", "ap6212a"},
{BCM43430_CHIP_ID, 2, DONT_CARE, FALSE, "bcm43436b0", "ap6236"},
{BCM43012_CHIP_ID, 1, DONT_CARE, TRUE, "bcm43013b0", ""},
{BCM4334_CHIP_ID, 3, DONT_CARE, FALSE, "bcm4334b1_ag", ""},
{BCM43340_CHIP_ID, 2, DONT_CARE, FALSE, "bcm43341b0_ag", ""},
{BCM43341_CHIP_ID, 2, DONT_CARE, FALSE, "bcm43341b0_ag", ""},
{BCM4324_CHIP_ID, 5, DONT_CARE, FALSE, "bcm43241b4_ag", "nvram_ap62x2.txt"},
{BCM4335_CHIP_ID, 2, DONT_CARE, FALSE, "bcm4339a0_ag", "nvram_AP6335.txt"},
{BCM4339_CHIP_ID, 1, DONT_CARE, FALSE, "bcm4339a0_ag", "nvram_AP6335.txt"},
{BCM4345_CHIP_ID, 6, DONT_CARE, FALSE, "bcm43455c0_ag", "nvram_ap6255.txt"},
{BCM4324_CHIP_ID, 5, DONT_CARE, FALSE, "bcm43241b4_ag", "ap62x2"},
{BCM4335_CHIP_ID, 2, DONT_CARE, FALSE, "bcm4339a0_ag", "AP6335"},
{BCM4339_CHIP_ID, 1, DONT_CARE, FALSE, "bcm4339a0_ag", "AP6335"},
{BCM4345_CHIP_ID, 6, DONT_CARE, FALSE, "bcm43455c0_ag", "ap6255"},
{BCM43454_CHIP_ID, 6, DONT_CARE, FALSE, "bcm43455c0_ag", ""},
{BCM4345_CHIP_ID, 9, DONT_CARE, FALSE, "bcm43456c5_ag", "nvram_ap6256.txt"},
{BCM4345_CHIP_ID, 9, DONT_CARE, FALSE, "bcm43456c5_ag", "ap6256"},
{BCM43454_CHIP_ID, 9, DONT_CARE, FALSE, "bcm43456c5_ag", ""},
{BCM4354_CHIP_ID, 1, DONT_CARE, FALSE, "bcm4354a1_ag", "nvram_ap6354.txt"},
{BCM4354_CHIP_ID, 2, DONT_CARE, FALSE, "bcm4356a2_ag", "nvram_ap6356.txt"},
{BCM4356_CHIP_ID, 2, DONT_CARE, FALSE, "bcm4356a2_ag", "nvram_ap6356.txt"},
{BCM4354_CHIP_ID, 1, DONT_CARE, FALSE, "bcm4354a1_ag", "ap6354"},
{BCM4354_CHIP_ID, 2, DONT_CARE, FALSE, "bcm4356a2_ag", "ap6356"},
{BCM4356_CHIP_ID, 2, DONT_CARE, FALSE, "bcm4356a2_ag", "ap6356"},
{BCM4371_CHIP_ID, 2, DONT_CARE, FALSE, "bcm4356a2_ag", ""},
{BCM43569_CHIP_ID, 3, DONT_CARE, FALSE, "bcm4358a3_ag", ""},
{BCM4359_CHIP_ID, 5, DONT_CARE, FALSE, "bcm4359b1_ag", ""},
{BCM4359_CHIP_ID, 9, DONT_CARE, FALSE, "bcm4359c0_ag", "nvram_ap6398s.txt"},
{BCM4359_CHIP_ID, 9, DONT_CARE, FALSE, "bcm4359c0_ag", "ap6398s"},
{BCM4362_CHIP_ID, 0, DONT_CARE, TRUE, "bcm43752a0_ag", ""},
#endif
#ifdef BCMPCIE
@ -480,6 +480,9 @@ dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path)
(row->ag_type == ag_type || row->ag_type == DONT_CARE)) {
strcpy(name_ptr, "fw_");
strcat(fw_path, row->chip_name);
#ifdef BCMUSBDEV_COMPOSITE
strcat(fw_path, "_cusb");
#endif
if (fw_type == FW_TYPE_APSTA)
strcat(fw_path, "_apsta.bin");
else if (fw_type == FW_TYPE_P2P)
@ -573,7 +576,12 @@ dhd_conf_set_nv_name_by_chip(dhd_pub_t *dhd, char *nv_path)
for (i = 0; i < sizeof(chip_name_map)/sizeof(chip_name_map[0]); i++) {
const cihp_name_map_t* row = &chip_name_map[i];
if (row->chip == chip && row->chiprev == chiprev && strlen(row->module_name)) {
strcpy(name_ptr, row->module_name);
strcpy(name_ptr, "nvram_");
strcat(name_ptr, row->module_name);
#ifdef BCMUSBDEV_COMPOSITE
strcat(name_ptr, "_cusb");
#endif
strcat(name_ptr, ".txt");
}
}
@ -638,7 +646,7 @@ dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path)
}
i--;
}
name_ptr = conf_path[i];
name_ptr = &conf_path[i];
for (i = 0; i < sizeof(chip_name_map)/sizeof(chip_name_map[0]); i++) {
const cihp_name_map_t* row = &chip_name_map[i];
@ -757,28 +765,23 @@ dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec)
}
int
dhd_conf_map_country_list(dhd_pub_t *dhd, wl_country_t *cspec, int nodfs)
dhd_conf_map_country_list(dhd_pub_t *dhd, wl_country_t *cspec)
{
int bcmerror = -1, i;
struct dhd_conf *conf = dhd->conf;
conf_country_list_t *country_list;
if ((nodfs > 0 || dhd->op_mode & DHD_FLAG_HOSTAP_MODE) &&
conf->country_list_nodfs.count > 0) {
country_list = &conf->country_list_nodfs;
} else {
country_list = &conf->country_list;
}
conf_country_list_t *country_list = &conf->country_list;
for (i = 0; i < country_list->count; i++) {
if (!strncmp(cspec->country_abbrev, country_list->cspec[i]->country_abbrev, 2)) {
memcpy(cspec->ccode, country_list->cspec[i]->ccode, WLC_CNTRY_BUF_SZ);
cspec->rev = country_list->cspec[i]->rev;
printf("%s: %s/%d\n", __FUNCTION__, cspec->ccode, cspec->rev);
return 0;
bcmerror = 0;
}
}
if (!bcmerror)
printf("%s: %s/%d\n", __FUNCTION__, cspec->ccode, cspec->rev);
return bcmerror;
}
@ -823,12 +826,12 @@ dhd_conf_fix_country(dhd_pub_t *dhd)
dtoh32(list->count)<11)) {
CONFIG_ERROR(("%s: bcmerror=%d, # of channels %d\n",
__FUNCTION__, bcmerror, dtoh32(list->count)));
dhd_conf_map_country_list(dhd, &dhd->conf->cspec, 0);
dhd_conf_map_country_list(dhd, &dhd->conf->cspec);
if ((bcmerror = dhd_conf_set_country(dhd, &dhd->conf->cspec)) < 0) {
strcpy(cspec.country_abbrev, "US");
cspec.rev = 0;
strcpy(cspec.ccode, "US");
dhd_conf_map_country_list(dhd, &cspec, 0);
dhd_conf_map_country_list(dhd, &cspec);
dhd_conf_set_country(dhd, &cspec);
}
}
@ -1677,8 +1680,6 @@ dhd_conf_read_country_list(dhd_pub_t *dhd, char *full_param, uint len_param)
*/
if (!strncmp("country_list=", full_param, len_param)) {
country_list = &dhd->conf->country_list;
} else if (!strncmp("country_list_nodfs=", full_param, len_param)) {
country_list = &dhd->conf->country_list_nodfs;
}
if (country_list) {
pick_tmp = data;
@ -1716,8 +1717,6 @@ dhd_conf_read_country_list(dhd_pub_t *dhd, char *full_param, uint len_param)
}
if (!strncmp("country_list=", full_param, len_param)) {
printf("%s: %d country in list\n", __FUNCTION__, conf->country_list.count);
} else if (!strncmp("country_list_nodfs=", full_param, len_param)) {
printf("%s: %d nodfs country in list\n", __FUNCTION__, conf->country_list.count);
}
}
else
@ -1976,6 +1975,7 @@ dhd_conf_read_sdio_params(dhd_pub_t *dhd, char *full_param, uint len_param)
conf->sd_f2_blocksize = (int)simple_strtol(data, NULL, 10);
printf("%s: sd_f2_blocksize = %d\n", __FUNCTION__, conf->sd_f2_blocksize);
}
#if defined(HW_OOB)
else if (!strncmp("oob_enabled_later=", full_param, len_param)) {
if (!strncmp(data, "0", 1))
conf->oob_enabled_later = FALSE;
@ -1983,6 +1983,7 @@ dhd_conf_read_sdio_params(dhd_pub_t *dhd, char *full_param, uint len_param)
conf->oob_enabled_later = TRUE;
printf("%s: oob_enabled_later = %d\n", __FUNCTION__, conf->oob_enabled_later);
}
#endif
else if (!strncmp("dpc_cpucore=", full_param, len_param)) {
conf->dpc_cpucore = (int)simple_strtol(data, NULL, 10);
printf("%s: dpc_cpucore = %d\n", __FUNCTION__, conf->dpc_cpucore);
@ -2029,16 +2030,9 @@ dhd_conf_read_sdio_params(dhd_pub_t *dhd, char *full_param, uint len_param)
printf("%s: deferred_tx_len = %d\n", __FUNCTION__, conf->deferred_tx_len);
}
else if (!strncmp("txctl_tmo_fix=", full_param, len_param)) {
conf->txctl_tmo_fix = (int)simple_strtol(data, NULL, 10);
conf->txctl_tmo_fix = (int)simple_strtol(data, NULL, 0);
printf("%s: txctl_tmo_fix = %d\n", __FUNCTION__, conf->txctl_tmo_fix);
}
else if (!strncmp("tx_in_rx=", full_param, len_param)) {
if (!strncmp(data, "0", 1))
conf->tx_in_rx = FALSE;
else
conf->tx_in_rx = TRUE;
printf("%s: tx_in_rx = %d\n", __FUNCTION__, conf->tx_in_rx);
}
else if (!strncmp("tx_max_offset=", full_param, len_param)) {
conf->tx_max_offset = (int)simple_strtol(data, NULL, 10);
printf("%s: tx_max_offset = %d\n", __FUNCTION__, conf->tx_max_offset);
@ -2261,10 +2255,6 @@ dhd_conf_read_others(dhd_pub_t *dhd, char *full_param, uint len_param)
printf("%s: dhd_rxbound = %d\n", __FUNCTION__, dhd_rxbound);
}
#endif
else if (!strncmp("num_different_channels=", full_param, len_param)) {
conf->num_different_channels = (int)simple_strtol(data, NULL, 10);
printf("%s: num_different_channels = %d\n", __FUNCTION__, conf->num_different_channels);
}
else if (!strncmp("tsq=", full_param, len_param)) {
conf->tsq = (int)simple_strtol(data, NULL, 10);
printf("%s: tsq = %d\n", __FUNCTION__, conf->tsq);
@ -2277,6 +2267,14 @@ dhd_conf_read_others(dhd_pub_t *dhd, char *full_param, uint len_param)
conf->dhd_ioctl_timeout_msec = (int)simple_strtol(data, NULL, 10);
printf("%s: dhd_ioctl_timeout_msec = %d\n", __FUNCTION__, conf->dhd_ioctl_timeout_msec);
}
else if (!strncmp("in4way=", full_param, len_param)) {
conf->in4way = (int)simple_strtol(data, NULL, 0);
printf("%s: in4way = 0x%x\n", __FUNCTION__, conf->in4way);
}
else if (!strncmp("max_wait_gc_time=", full_param, len_param)) {
conf->max_wait_gc_time = (int)simple_strtol(data, NULL, 0);
printf("%s: max_wait_gc_time = %d\n", __FUNCTION__, conf->max_wait_gc_time);
}
else if (!strncmp("wl_preinit=", full_param, len_param)) {
if (!(conf->wl_preinit = kmalloc(len_param+1, GFP_KERNEL))) {
CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
@ -2475,8 +2473,8 @@ dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable)
conf->txglom_mode==SDPCM_TXGLOM_MDESC?"multi-desc":"copy");
printf("%s: txglomsize=%d, deferred_tx_len=%d\n", __FUNCTION__,
conf->txglomsize, conf->deferred_tx_len);
printf("%s: tx_in_rx=%d, txinrx_thres=%d, dhd_txminmax=%d\n", __FUNCTION__,
conf->tx_in_rx, conf->txinrx_thres, conf->dhd_txminmax);
printf("%s: txinrx_thres=%d, dhd_txminmax=%d\n", __FUNCTION__,
conf->txinrx_thres, conf->dhd_txminmax);
printf("%s: tx_max_offset=%d, txctl_tmo_fix=%d\n", __FUNCTION__,
conf->tx_max_offset, conf->txctl_tmo_fix);
@ -2539,8 +2537,8 @@ dhd_conf_set_wl_preinit(dhd_pub_t *dhd, char *data)
char name[32], *pch, *pick_tmp, *pick_tmp2;
/* Process wl_preinit:
* wl_preinit=[cmd]/[val], [cmd]/[val] \
* Ex: wl_preinit=86/0, mpc/0
* wl_preinit=[cmd]=[val], [cmd]=[val]
* Ex: wl_preinit=86=0, mpc=0
*/
pick_tmp = data;
while (pick_tmp && (pick_tmp2 = bcmstrtok(&pick_tmp, ",", 0)) != NULL) {
@ -2577,15 +2575,13 @@ dhd_conf_postinit_ioctls(dhd_pub_t *dhd)
struct dhd_conf *conf = dhd->conf;
dhd_conf_set_intiovar(dhd, WLC_UP, "up", 0, 0, FALSE);
dhd_conf_map_country_list(dhd, &conf->cspec, 0);
dhd_conf_map_country_list(dhd, &conf->cspec);
dhd_conf_set_country(dhd, &conf->cspec);
dhd_conf_fix_country(dhd);
dhd_conf_get_country(dhd, &dhd->dhd_cspec);
dhd_conf_set_intiovar(dhd, WLC_SET_BAND, "WLC_SET_BAND", conf->band, 0, FALSE);
dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "bcn_timeout", conf->bcn_timeout, 0, FALSE);
if (conf->fw_type == FW_TYPE_MESH)
conf->pm = PM_OFF;
dhd_conf_set_intiovar(dhd, WLC_SET_PM, "PM", conf->pm, 0, FALSE);
dhd_conf_set_intiovar(dhd, WLC_SET_SRL, "WLC_SET_SRL", conf->srl, 0, TRUE);
dhd_conf_set_intiovar(dhd, WLC_SET_LRL, "WLC_SET_LRL", conf->lrl, 0, FALSE);
@ -2637,7 +2633,6 @@ dhd_conf_preinit(dhd_pub_t *dhd)
dhd_conf_free_chip_nv_path_list(&conf->nv_by_chip);
#endif
dhd_conf_free_country_list(&conf->country_list);
dhd_conf_free_country_list(&conf->country_list_nodfs);
if (conf->magic_pkt_filter_add) {
kfree(conf->magic_pkt_filter_add);
conf->magic_pkt_filter_add = NULL;
@ -2713,14 +2708,15 @@ dhd_conf_preinit(dhd_pub_t *dhd)
conf->txglom_ext = FALSE;
conf->tx_max_offset = 0;
conf->txglomsize = SDPCM_DEFGLOM_SIZE;
conf->txctl_tmo_fix = 300;
conf->tx_in_rx = TRUE;
conf->txctl_tmo_fix = -1;
conf->txglom_mode = SDPCM_TXGLOM_CPY;
conf->deferred_tx_len = 0;
conf->dhd_txminmax = 1;
conf->txinrx_thres = -1;
conf->sd_f2_blocksize = 0;
#if defined(HW_OOB)
conf->oob_enabled_later = FALSE;
#endif
conf->orphan_move = 0;
#endif
#ifdef BCMPCIE
@ -2733,7 +2729,6 @@ dhd_conf_preinit(dhd_pub_t *dhd)
conf->pm = -1;
conf->pm_in_suspend = -1;
conf->suspend_bcn_li_dtim = -1;
conf->num_different_channels = -1;
conf->xmit_in_suspend = TRUE;
conf->ap_in_suspend = 0;
#ifdef SUSPEND_EVENT
@ -2760,6 +2755,8 @@ dhd_conf_preinit(dhd_pub_t *dhd)
conf->pktprio8021x = -1;
conf->ctrl_resched = 2;
conf->dhd_ioctl_timeout_msec = 0;
conf->in4way = NO_SCAN_IN4WAY | WAIT_DISCONNECTED;
conf->max_wait_gc_time = 300;
#ifdef ISAM_PREINIT
memset(conf->isam_init, 0, sizeof(conf->isam_init));
memset(conf->isam_config, 0, sizeof(conf->isam_config));
@ -2768,9 +2765,11 @@ dhd_conf_preinit(dhd_pub_t *dhd)
for (i=0; i<MCHAN_MAX_NUM; i++) {
memset(&conf->mchan[i], -1, sizeof(mchan_params_t));
}
if (conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID ||
conf->chip == BCM4371_CHIP_ID || conf->chip == BCM43569_CHIP_ID ||
conf->chip == BCM4359_CHIP_ID || conf->chip == BCM4362_CHIP_ID) {
if (conf->chip == BCM4335_CHIP_ID || conf->chip == BCM4339_CHIP_ID ||
conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID ||
conf->chip == BCM4345_CHIP_ID || conf->chip == BCM4371_CHIP_ID ||
conf->chip == BCM43569_CHIP_ID || conf->chip == BCM4359_CHIP_ID ||
conf->chip == BCM4362_CHIP_ID) {
#ifdef DHDTCPACK_SUPPRESS
#ifdef BCMSDIO
conf->tcpack_sup_mode = TCPACK_SUP_REPLACE;
@ -2786,7 +2785,6 @@ dhd_conf_preinit(dhd_pub_t *dhd)
conf->dhd_txminmax = -1;
conf->txinrx_thres = 128;
conf->sd_f2_blocksize = CUSTOM_SDIO_F2_BLKSIZE;
conf->oob_enabled_later = TRUE;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
conf->orphan_move = 1;
#else
@ -2830,7 +2828,6 @@ dhd_conf_reset(dhd_pub_t *dhd)
dhd_conf_free_chip_nv_path_list(&dhd->conf->nv_by_chip);
#endif
dhd_conf_free_country_list(&dhd->conf->country_list);
dhd_conf_free_country_list(&dhd->conf->country_list_nodfs);
if (dhd->conf->magic_pkt_filter_add) {
kfree(dhd->conf->magic_pkt_filter_add);
dhd->conf->magic_pkt_filter_add = NULL;
@ -2883,7 +2880,6 @@ dhd_conf_detach(dhd_pub_t *dhd)
dhd_conf_free_chip_nv_path_list(&dhd->conf->nv_by_chip);
#endif
dhd_conf_free_country_list(&dhd->conf->country_list);
dhd_conf_free_country_list(&dhd->conf->country_list_nodfs);
if (dhd->conf->magic_pkt_filter_add) {
kfree(dhd->conf->magic_pkt_filter_add);
dhd->conf->magic_pkt_filter_add = NULL;

View File

@ -101,6 +101,35 @@ typedef struct mchan_params {
int miracast_mode;
} mchan_params_t;
enum in4way_flags {
NO_SCAN_IN4WAY = (1 << (0)),
NO_BTC_IN4WAY = (1 << (1)),
DONT_DELETE_GC_AFTER_WPS = (1 << (2)),
WAIT_DISCONNECTED = (1 << (3)),
};
enum eapol_status {
EAPOL_STATUS_NONE = 0,
EAPOL_STATUS_WPS_REQID,
EAPOL_STATUS_WPS_RSPID,
EAPOL_STATUS_WPS_WSC_START,
EAPOL_STATUS_WPS_M1,
EAPOL_STATUS_WPS_M2,
EAPOL_STATUS_WPS_M3,
EAPOL_STATUS_WPS_M4,
EAPOL_STATUS_WPS_M5,
EAPOL_STATUS_WPS_M6,
EAPOL_STATUS_WPS_M7,
EAPOL_STATUS_WPS_M8,
EAPOL_STATUS_WPS_DONE,
EAPOL_STATUS_WPA_START,
EAPOL_STATUS_WPA_M1,
EAPOL_STATUS_WPA_M2,
EAPOL_STATUS_WPA_M3,
EAPOL_STATUS_WPA_M4,
EAPOL_STATUS_WPA_END
};
typedef struct dhd_conf {
uint chip;
uint chiprev;
@ -109,7 +138,6 @@ typedef struct dhd_conf {
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 bw_cap[2];
wl_country_t cspec;
@ -148,7 +176,6 @@ typedef struct dhd_conf {
int tx_max_offset;
uint txglomsize;
int txctl_tmo_fix;
bool tx_in_rx;
bool txglom_mode;
uint deferred_tx_len;
/*txglom_bucket_size:
@ -176,7 +203,6 @@ typedef struct dhd_conf {
uint8 tcpack_sup_mode;
#endif
int pktprio8021x;
int num_different_channels;
int xmit_in_suspend;
int ap_in_suspend;
#ifdef SUSPEND_EVENT
@ -202,6 +228,9 @@ typedef struct dhd_conf {
struct mchan_params mchan[MCHAN_MAX_NUM];
char *wl_preinit;
int tsq;
uint eapol_status;
uint in4way;
uint max_wait_gc_time;
} dhd_conf_t;
#ifdef BCMSDIO
@ -227,7 +256,7 @@ int dhd_conf_set_bufiovar(dhd_pub_t *dhd, uint cmd, char *name, char *buf, int l
uint dhd_conf_get_band(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_map_country_list(dhd_pub_t *dhd, wl_country_t *cspec, int nodfs);
int dhd_conf_map_country_list(dhd_pub_t *dhd, wl_country_t *cspec);
int dhd_conf_fix_country(dhd_pub_t *dhd);
bool dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel);
void dhd_conf_set_wme(dhd_pub_t *dhd, int mode);
@ -240,6 +269,7 @@ int dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev);
uint dhd_conf_get_chip(void *context);
uint dhd_conf_get_chiprev(void *context);
int dhd_conf_get_pm(dhd_pub_t *dhd);
#ifdef PROP_TXSTATUS
int dhd_conf_get_disable_proptx(dhd_pub_t *dhd);
#endif

View File

@ -301,9 +301,10 @@ int dhd_wlan_init_gpio(void)
dhd_wlan_resources[0].start = dhd_wlan_resources[0].end = host_oob_irq;
dhd_wlan_resources[0].flags = 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);
printf("%s: WL_HOST_WAKE=%d, oob_irq=%d, oob_irq_flags=0x%x\n", __FUNCTION__,
gpio_wl_host_wake, host_oob_irq, host_oob_irq_flags);
#endif /* CUSTOMER_OOB */
printf("%s: WL_REG_ON=%d\n", __FUNCTION__, gpio_wl_reg_on);
return 0;
}

View File

@ -378,8 +378,8 @@ int dhd_tcpack_suppress_set(dhd_pub_t *dhdp, uint8 mode)
goto exit;
}
DHD_TRACE(("%s: TCP ACK Suppress mode %d -> mode %d\n",
__FUNCTION__, dhdp->tcpack_sup_mode, mode));
printf("%s: TCP ACK Suppress mode %d -> mode %d\n",
__FUNCTION__, dhdp->tcpack_sup_mode, mode);
/* Pre-process routines to change a new mode as per previous mode */
switch (prev_mode) {

View File

@ -84,9 +84,6 @@
#include <dhd_bus.h>
#include <dhd_proto.h>
#include <dhd_config.h>
#ifdef WL_ESCAN
#include <wl_escan.h>
#endif
#include <dhd_dbg.h>
#include <dhd_debug.h>
#ifdef CONFIG_HAS_WAKELOCK
@ -259,9 +256,8 @@ extern bool ap_cfg_running;
extern bool ap_fw_loaded;
#endif
#ifdef DHD_8021X_DUMP
extern void dhd_dump_eapol_4way_message(char *ifname, char *dump_data, bool direction);
#endif /* DHD_8021X_DUMP */
extern void dhd_dump_eapol_4way_message(dhd_pub_t *dhd, char *ifname,
char *dump_data, bool direction);
#ifdef FIX_CPU_MIN_CLOCK
#include <linux/pm_qos.h>
@ -294,6 +290,9 @@ static u32 vendor_oui = CONFIG_DHD_SET_RANDOM_MAC_VAL;
#endif
#include <wl_android.h>
#ifdef WL_ESCAN
#include <wl_escan.h>
#endif
/* Maximum STA per radio */
#define DHD_MAX_STA 32
@ -4094,11 +4093,6 @@ _dhd_set_mac_address(dhd_info_t *dhd, int ifidx, uint8 *addr)
return ret;
}
#ifdef SOFTAP
extern struct net_device *ap_net_dev;
extern tsk_ctl_t ap_eth_ctl; /* ap netdev heper thread ctl */
#endif
#ifdef DHD_WMF
void dhd_update_psta_interface_for_sta(dhd_pub_t* dhdp, char* ifname, void* ea,
void* event_data)
@ -4475,22 +4469,6 @@ dhd_set_mac_addr_handler(void *handle, void *event_info, u8 event)
DHD_OS_WAKE_LOCK(&dhd->pub);
DHD_PERIM_LOCK(&dhd->pub);
#ifdef SOFTAP
{
unsigned long flags;
bool in_ap = FALSE;
DHD_GENERAL_LOCK(&dhd->pub, flags);
in_ap = (ap_net_dev != NULL);
DHD_GENERAL_UNLOCK(&dhd->pub, flags);
if (in_ap) {
DHD_ERROR(("attempt to set MAC for %s in AP Mode, blocked. \n",
ifp->net->name));
goto done;
}
}
#endif /* SOFTAP */
// terence 20160907: fix for not able to set mac when wlan0 is down
if (ifp == NULL || !ifp->set_macaddress) {
goto done;
@ -4541,23 +4519,6 @@ dhd_set_mcast_list_handler(void *handle, void *event_info, u8 event)
goto done;
}
#ifdef SOFTAP
{
bool in_ap = FALSE;
unsigned long flags;
DHD_GENERAL_LOCK(&dhd->pub, flags);
in_ap = (ap_net_dev != NULL);
DHD_GENERAL_UNLOCK(&dhd->pub, flags);
if (in_ap) {
DHD_ERROR(("set MULTICAST list for %s in AP Mode, blocked. \n",
ifp->net->name));
ifp->set_multicast = FALSE;
goto done;
}
}
#endif /* SOFTAP */
if (ifp == NULL || !dhd->pub.up) {
DHD_ERROR(("%s: interface info not available/down \n", __FUNCTION__));
goto done;
@ -4693,42 +4654,25 @@ static const char *_get_packet_type_str(uint16 type)
return packet_type_info[n].str;
}
#endif /* DHD_RX_DUMP || DHD_TX_DUMP */
#if defined(DHD_TX_DUMP)
void
dhd_tx_dump(struct net_device *ndev, osl_t *osh, void *pkt)
dhd_trx_dump(struct net_device *ndev, uint8 *dump_data, uint datalen, bool tx)
{
uint8 *dump_data;
uint16 protocol;
char *ifname;
dump_data = PKTDATA(osh, pkt);
protocol = (dump_data[12] << 8) | dump_data[13];
ifname = ndev ? ndev->name : "N/A";
DHD_ERROR(("TX DUMP[%s] - %s\n", ifname, _get_packet_type_str(protocol)));
if (protocol == ETHER_TYPE_802_1X) {
dhd_dump_eapol_4way_message(ifname, dump_data, TRUE);
if (protocol != ETHER_TYPE_BRCM) {
DHD_ERROR(("%s DUMP[%s] - %s\n", tx?"Tx":"Rx", ifname,
_get_packet_type_str(protocol)));
#if defined(DHD_TX_FULL_DUMP) || defined(DHD_RX_FULL_DUMP)
prhex("Data", dump_data, datalen);
#endif /* DHD_TX_FULL_DUMP || DHD_RX_FULL_DUMP */
}
#if defined(DHD_TX_FULL_DUMP)
{
int i;
uint datalen;
datalen = PKTLEN(osh, pkt);
for (i = 0; i < datalen; i++) {
printk("%02X ", dump_data[i]);
if ((i & 15) == 15)
printk("\n");
}
printk("\n");
}
#endif /* DHD_TX_FULL_DUMP */
}
#endif /* DHD_TX_DUMP */
#endif /* DHD_TX_DUMP || DHD_RX_DUMP */
/* This routine do not support Packet chain feature, Currently tested for
* proxy arp feature
@ -4888,9 +4832,7 @@ __dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf)
#endif /* DHD_LOSSLESS_ROAMING */
DBG_EVENT_LOG(dhdp, WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED);
atomic_inc(&dhd->pend_8021x_cnt);
#if defined(DHD_8021X_DUMP)
dhd_dump_eapol_4way_message(dhd_ifname(dhdp, ifidx), pktdata, TRUE);
#endif /* DHD_8021X_DUMP */
dhd_dump_eapol_4way_message(dhdp, dhd_ifname(dhdp, ifidx), pktdata, TRUE);
}
if (ntoh16(eh->ether_type) == ETHER_TYPE_IP) {
@ -4943,8 +4885,8 @@ __dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf)
#endif
#if defined(DHD_TX_DUMP)
ndev = dhd_idx2net(dhdp, ifidx);
dhd_tx_dump(ndev, dhdp->osh, pktbuf);
dhd_trx_dump(dhd_idx2net(dhdp, ifidx), PKTDATA(dhdp->osh, pktbuf),
PKTLEN(dhdp->osh, pktbuf), TRUE);
#endif
/* terence 20150901: Micky add to ajust the 802.1X priority */
/* Set the 802.1X packet with the highest priority 7 */
@ -5719,10 +5661,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
void *skbhead = NULL;
void *skbprev = NULL;
uint16 protocol;
#if defined(DHD_RX_DUMP) || defined(DHD_8021X_DUMP) || defined(DHD_DHCP_DUMP) || \
defined(DHD_ICMP_DUMP) || defined(DHD_WAKE_STATUS)
unsigned char *dump_data;
#endif /* DHD_RX_DUMP || DHD_8021X_DUMP || DHD_DHCP_DUMP || DHD_ICMP_DUMP || DHD_WAKE_STATUS */
#ifdef DHD_MCAST_REGEN
uint8 interface_role;
if_flow_lkup_t *if_flow_lkup;
@ -5953,17 +5892,12 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
eth = skb->data;
len = skb->len;
#if defined(DHD_RX_DUMP) || defined(DHD_8021X_DUMP) || defined(DHD_DHCP_DUMP) || \
defined(DHD_ICMP_DUMP) || defined(DHD_WAKE_STATUS)
dump_data = skb->data;
#endif /* DHD_RX_DUMP || DHD_8021X_DUMP || DHD_DHCP_DUMP || DHD_ICMP_DUMP || DHD_WAKE_STATUS */
protocol = (skb->data[12] << 8) | skb->data[13];
if (protocol == ETHER_TYPE_802_1X) {
DBG_EVENT_LOG(dhdp, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED);
#ifdef DHD_8021X_DUMP
dhd_dump_eapol_4way_message(dhd_ifname(dhdp, ifidx), dump_data, FALSE);
#endif /* DHD_8021X_DUMP */
dhd_dump_eapol_4way_message(dhdp, dhd_ifname(dhdp, ifidx), dump_data, FALSE);
}
if (protocol != ETHER_TYPE_BRCM && protocol == ETHER_TYPE_IP) {
@ -5975,33 +5909,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
#endif /* DHD_ICMP_DUMP */
}
#ifdef DHD_RX_DUMP
DHD_ERROR(("RX DUMP[%s] - %s\n",
dhd_ifname(dhdp, ifidx), _get_packet_type_str(protocol)));
if (protocol != ETHER_TYPE_BRCM) {
if (dump_data[0] == 0xFF) {
DHD_ERROR(("%s: BROADCAST\n", __FUNCTION__));
if ((dump_data[12] == 8) &&
(dump_data[13] == 6)) {
DHD_ERROR(("%s: ARP %d\n",
__FUNCTION__, dump_data[0x15]));
}
} else if (dump_data[0] & 1) {
DHD_ERROR(("%s: MULTICAST: " MACDBG "\n",
__FUNCTION__, MAC2STRDBG(dump_data)));
}
#ifdef DHD_RX_FULL_DUMP
{
int k;
for (k = 0; k < skb->len; k++) {
printk("%02X ", dump_data[k]);
if ((k & 15) == 15)
printk("\n");
}
printk("\n");
}
#endif /* DHD_RX_FULL_DUMP */
}
dhd_trx_dump(dhd_idx2net(dhdp, ifidx), dump_data, skb->len, FALSE);
#endif /* DHD_RX_DUMP */
#if defined(DHD_WAKE_STATUS) && defined(DHD_WAKEPKT_DUMP)
if (pkt_wake) {
@ -8376,7 +8284,7 @@ dhd_stop(struct net_device *net)
#else
wl_android_wifi_off(net, TRUE);
#ifdef WL_EXT_IAPSTA
wl_ext_iapsta_dettach_netdev();
wl_ext_iapsta_dettach_netdev(net, ifidx);
#endif
} else {
if (dhd->pub.conf->deepsleep)
@ -8550,7 +8458,7 @@ dhd_open(struct net_device *net)
if (!dhd_download_fw_on_driverload) {
DHD_ERROR(("\n%s\n", dhd_version));
#ifdef WL_EXT_IAPSTA
wl_ext_iapsta_attach_netdev(net, ifidx);
wl_ext_iapsta_attach_netdev(net, ifidx, dhd->iflist[ifidx]->bssidx);
#endif
#if defined(USE_INITIAL_SHORT_DWELL_TIME)
g_first_broadcast_scan = TRUE;
@ -9079,6 +8987,9 @@ dhd_remove_if(dhd_pub_t *dhdpub, int ifidx, bool need_rtnl_lock)
unregister_netdev(ifp->net);
else
unregister_netdevice(ifp->net);
#ifdef WL_EXT_IAPSTA
wl_ext_iapsta_dettach_netdev(ifp->net, ifidx);
#endif
}
ifp->net = NULL;
}
@ -9428,6 +9339,9 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen
#elif defined(BCMDBUS)
wifi_adapter_info_t *adapter = data;
#endif
#ifdef GET_CUSTOM_MAC_ENABLE
char hw_ether[62];
#endif /* GET_CUSTOM_MAC_ENABLE */
dhd_attach_states_t dhd_state = DHD_ATTACH_STATE_INIT;
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
@ -9472,7 +9386,8 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen
#endif /* BT_OVER_SDIO */
#ifdef GET_CUSTOM_MAC_ENABLE
wifi_platform_get_mac_addr(dhd->adapter, dhd->pub.mac.octet);
wifi_platform_get_mac_addr(dhd->adapter, hw_ether);
bcopy(hw_ether, dhd->pub.mac.octet, sizeof(struct ether_addr));
#endif /* GET_CUSTOM_MAC_ENABLE */
#ifdef CUSTOM_FORCE_NODFS_FLAG
dhd->pub.dhd_cflags |= WLAN_PLAT_NODFS_FLAG;
@ -9658,18 +9573,26 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen
dhd_log_dump_init(&dhd->pub);
#endif /* DHD_LOG_DUMP */
#if defined(WL_WIRELESS_EXT)
/* Attach and link in the iw */
if (!(dhd_state & DHD_ATTACH_STATE_CFG80211)) {
if (wl_iw_attach(net, (void *)&dhd->pub) != 0) {
DHD_ERROR(("wl_iw_attach failed\n"));
goto fail;
}
dhd_state |= DHD_ATTACH_STATE_WL_ATTACH;
}
#ifdef WL_ESCAN
wl_escan_attach(net, &dhd->pub);
if (wl_escan_attach(net, &dhd->pub) != 0) {
DHD_ERROR(("wl_escan_attach failed\n"));
goto fail;
}
#else
/* Attach and link in the iw */
if (wl_iw_attach(net, &dhd->pub) != 0) {
DHD_ERROR(("wl_iw_attach failed\n"));
goto fail;
}
dhd_state |= DHD_ATTACH_STATE_WL_ATTACH;
#endif /* WL_ESCAN */
#endif /* defined(WL_WIRELESS_EXT) */
#ifdef WL_EXT_IAPSTA
if (wl_ext_iapsta_attach(&dhd->pub) != 0) {
DHD_ERROR(("wl_ext_iapsta_attach failed\n"));
goto fail;
}
#endif
#ifdef SHOW_LOGTRACE
ret = dhd_init_logstrs_array(osh, &dhd->event_data);
@ -11002,7 +10925,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
DHD_TRACE(("Enter %s\n", __FUNCTION__));
#ifdef DHDTCPACK_SUPPRESS
printf("%s: Set tcpack_sup_mode %d\n", __FUNCTION__, dhd->conf->tcpack_sup_mode);
dhd_tcpack_suppress_set(dhd, dhd->conf->tcpack_sup_mode);
#endif
dhd->op_mode = 0;
@ -11946,7 +11868,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
} else if (ret >= 1) {
disable_proptx = 1;
wlfc_enable = FALSE;
/* terence 20161229: we should set ampdu_hostreorder=0 when disalbe_proptx=1 */
/* terence 20161229: we should set ampdu_hostreorder=0 when disable_proptx=1 */
hostreorder = 0;
}
@ -12675,16 +12597,14 @@ dhd_register_if(dhd_pub_t *dhdp, int ifidx, bool need_rtnl_lock)
printf("%s\n", dhd_version);
#ifdef WL_EXT_IAPSTA
else
wl_ext_iapsta_attach_netdev(net, ifidx);
wl_ext_iapsta_attach_netdev(net, ifidx, ifp->bssidx);
#endif
#ifdef WLMESH
if (ifidx != 0 && dhdp->conf->fw_type == FW_TYPE_MESH) {
if (_dhd_set_mac_address(dhd, ifidx, temp_addr) == 0)
if (ifidx != 0) {
if (_dhd_set_mac_address(dhd, ifidx, net->dev_addr) == 0)
DHD_INFO(("%s: MACID is overwritten\n", __FUNCTION__));
else
DHD_ERROR(("%s: _dhd_set_mac_address() failed\n", __FUNCTION__));
}
#endif
if (need_rtnl_lock)
err = register_netdev(net);
@ -12697,7 +12617,7 @@ dhd_register_if(dhd_pub_t *dhdp, int ifidx, bool need_rtnl_lock)
}
#ifdef WL_EXT_IAPSTA
if (ifidx == 0)
wl_ext_iapsta_attach_netdev(net, ifidx);
wl_ext_iapsta_attach_netdev(net, ifidx, ifp->bssidx);
wl_ext_iapsta_attach_name(net, ifidx);
#endif
@ -12912,14 +12832,18 @@ void dhd_detach(dhd_pub_t *dhdp)
#endif /* CONFIG_HAS_EARLYSUSPEND && DHD_USE_EARLYSUSPEND */
#if defined(WL_WIRELESS_EXT)
if (dhd->dhd_state & DHD_ATTACH_STATE_WL_ATTACH) {
/* Detatch and unlink in the iw */
wl_iw_detach();
}
#ifdef WL_ESCAN
wl_escan_detach(dhdp);
#else
if (dhd->dhd_state & DHD_ATTACH_STATE_WL_ATTACH) {
/* Detatch and unlink in the iw */
wl_iw_detach(dhdp);
}
#endif /* WL_ESCAN */
#endif /* defined(WL_WIRELESS_EXT) */
#ifdef WL_EXT_IAPSTA
wl_ext_iapsta_dettach(dhdp);
#endif
#ifdef DHD_ULP
dhd_ulp_deinit(dhd->pub.osh, dhdp);

View File

@ -117,6 +117,7 @@ static int dhdsdio_resume(void *context);
#define MAX_MEMBLOCK (32 * 1024) /* Block size used for downloading of dongle image */
#define MAX_DATA_BUF (64 * 1024) /* Must be large enough to hold biggest possible glom */
#define MAX_MEM_BUF 4096
#ifndef DHD_FIRSTREAD
#define DHD_FIRSTREAD 32
@ -440,6 +441,7 @@ typedef struct dhd_bus {
#endif /* defined (BT_OVER_SDIO) */
uint txglomframes; /* Number of tx glom frames (superframes) */
uint txglompkts; /* Number of packets from tx glom frames */
uint8 *membuf; /* Buffer for dhdsdio_membytes */
} dhd_bus_t;
@ -2773,13 +2775,15 @@ dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen)
/* Need to lock here to protect txseq and SDIO tx calls */
dhd_os_sdlock(bus->dhd);
if (bus->dhd->conf->txctl_tmo_fix > 0 && !TXCTLOK(bus)) {
bus->ctrl_wait = TRUE;
dhd_os_sdunlock(bus->dhd);
wait_event_interruptible_timeout(bus->ctrl_tx_wait, TXCTLOK(bus),
msecs_to_jiffies(bus->dhd->conf->txctl_tmo_fix));
dhd_os_sdlock(bus->dhd);
bus->ctrl_wait = FALSE;
}
dhd_os_sdlock(bus->dhd);
BUS_WAKE(bus);
@ -3372,6 +3376,7 @@ dhdsdio_membytes(dhd_bus_t *bus, bool write, uint32 address, uint8 *data, uint s
int bcmerror = 0;
uint32 sdaddr;
uint dsize;
uint8 *pdata;
/* In remap mode, adjust address beyond socram and redirect
* to devram at SOCDEVRAM_BP_ADDR since remap address > orig_ramsize
@ -3400,10 +3405,19 @@ dhdsdio_membytes(dhd_bus_t *bus, bool write, uint32 address, uint8 *data, uint s
DHD_INFO(("%s: %s %d bytes at offset 0x%08x in window 0x%08x\n",
__FUNCTION__, (write ? "write" : "read"), dsize, sdaddr,
(address & SBSDIO_SBWINDOW_MASK)));
if ((bcmerror = bcmsdh_rwdata(bus->sdh, write, sdaddr, data, dsize))) {
if (dsize <= MAX_MEM_BUF) {
pdata = bus->membuf;
if (write)
memcpy(bus->membuf, data, dsize);
} else {
pdata = data;
}
if ((bcmerror = bcmsdh_rwdata(bus->sdh, write, sdaddr, pdata, dsize))) {
DHD_ERROR(("%s: membytes transfer failed\n", __FUNCTION__));
break;
}
if (dsize <= MAX_MEM_BUF && !write)
memcpy(data, bus->membuf, dsize);
/* Adjust for next transfer (if any) */
if ((size -= dsize)) {
@ -5848,8 +5862,7 @@ dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished)
dhdsdio_sendpendctl(bus);
} else if (bus->dotxinrx && (bus->clkstate == CLK_AVAIL) &&
!bus->fcstate && DATAOK(bus) &&
(pktq_mlen(&bus->txq, ~bus->flowcontrol) > bus->txinrx_thres) &&
bus->dhd->conf->tx_in_rx) {
(pktq_mlen(&bus->txq, ~bus->flowcontrol) > bus->txinrx_thres)) {
dhdsdio_sendfromq(bus, dhd_txbound);
#ifdef DHDTCPACK_SUPPRESS
/* In TCPACK_SUP_DELAYTX mode, do txinrx only if
@ -6736,7 +6749,8 @@ dhdsdio_dpc(dhd_bus_t *bus)
* or clock availability. (Allows tx loop to check ipend if desired.)
* (Unless register access seems hosed, as we may not be able to ACK...)
*/
if (!bus->dhd->conf->oob_enabled_later && bus->intr && bus->intdis && !bcmsdh_regfail(sdh)) {
if (bus->intr && bus->intdis && !bcmsdh_regfail(sdh) &&
!(bus->dhd->conf->oob_enabled_later && !bus->ctrl_frame_stat)) {
DHD_INTR(("%s: enable SDIO interrupts, rxdone %d framecnt %d\n",
__FUNCTION__, rxdone, framecnt));
bus->intdis = FALSE;
@ -6794,7 +6808,7 @@ dhdsdio_dpc(dhd_bus_t *bus)
}
/* Resched the DPC if ctrl cmd is pending on bus credit */
if (bus->ctrl_frame_stat) {
if (bus->dhd->conf->txctl_tmo_fix > 0) {
if (bus->dhd->conf->txctl_tmo_fix) {
set_current_state(TASK_INTERRUPTIBLE);
if (!kthread_should_stop())
schedule_timeout(1);
@ -6842,7 +6856,8 @@ dhdsdio_dpc(dhd_bus_t *bus)
* or clock availability. (Allows tx loop to check ipend if desired.)
* (Unless register access seems hosed, as we may not be able to ACK...)
*/
if (bus->dhd->conf->oob_enabled_later && bus->intr && bus->intdis && !bcmsdh_regfail(sdh)) {
if (bus->intr && bus->intdis && !bcmsdh_regfail(sdh) &&
(bus->dhd->conf->oob_enabled_later && !bus->ctrl_frame_stat)) {
DHD_INTR(("%s: enable SDIO interrupts, rxdone %d framecnt %d\n",
__FUNCTION__, rxdone, framecnt));
bus->intdis = FALSE;
@ -8151,6 +8166,23 @@ dhdsdio_probe_malloc(dhd_bus_t *bus, osl_t *osh, void *sdh)
DHD_OS_PREFREE(bus->dhd, bus->rxbuf, bus->rxblen);
goto fail;
}
/* Allocate buffer to membuf */
bus->membuf = MALLOC(osh, MAX_MEM_BUF);
if (bus->membuf == NULL) {
DHD_ERROR(("%s: MALLOC of %d-byte membuf failed\n",
__FUNCTION__, MAX_MEM_BUF));
if (bus->databuf) {
#ifndef CONFIG_DHD_USE_STATIC_BUF
MFREE(osh, bus->databuf, MAX_DATA_BUF);
#endif
bus->databuf = NULL;
}
/* release rxbuf which was already located as above */
if (!bus->rxblen)
DHD_OS_PREFREE(bus->dhd, bus->rxbuf, bus->rxblen);
goto fail;
}
memset(bus->membuf, 0, MAX_MEM_BUF);
/* Align the buffer */
if ((uintptr)bus->databuf % DHD_SDALIGN)
@ -8427,6 +8459,11 @@ dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh)
bus->databuf = NULL;
}
if (bus->membuf) {
MFREE(osh, bus->membuf, MAX_DATA_BUF);
bus->membuf = NULL;
}
if (bus->vars && bus->varsz) {
MFREE(osh, bus->vars, bus->varsz);
bus->vars = NULL;

View File

@ -52,7 +52,7 @@ enum dhd_prealloc_index {
#define DHD_PREALLOC_DATABUF_SIZE (64 * 1024)
#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_DHD_INFO_SIZE (32 * 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)
@ -252,6 +252,7 @@ static int dhd_init_wlan_mem(void)
{
int i;
int j;
printk(KERN_ERR "%s(): %s\n", __func__, DHD_STATIC_VERSION_STR);
for (i = 0; i < DHD_SKB_1PAGE_BUF_NUM; i++) {
wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_1PAGE_BUFSIZE);
@ -332,7 +333,7 @@ static int dhd_init_wlan_mem(void)
#endif /* BCMDHD_PCIE */
wlan_static_dhd_memdump_ram_buf = kmalloc(DHD_PREALLOC_MEMDUMP_RAM_SIZE, GFP_KERNEL);
if (!wlan_static_dhd_memdump_ram_buf)
if (!wlan_static_dhd_memdump_ram_buf)
goto err_mem_alloc;
pr_err("%s: sectoin %d, size=%d\n", __func__,
DHD_PREALLOC_MEMDUMP_RAM, DHD_PREALLOC_MEMDUMP_RAM_SIZE);
@ -446,8 +447,6 @@ static int dhd_init_wlan_mem(void)
static int __init
dhd_static_buf_init(void)
{
printk(KERN_ERR "%s(): %s\n", __func__, DHD_STATIC_VERSION_STR);
dhd_init_wlan_mem();
return 0;

View File

@ -255,6 +255,7 @@ typedef struct mesh_config_ie mesh_config_ie_t;
#define MESH_PEERING_STATE_STRINGS \
{"IDLE ", "OPNSNT", "CNFRCV", "OPNRCV", "ESTAB ", "HOLDNG"}
#ifdef WLMESH
typedef BWL_PRE_PACKED_STRUCT struct mesh_peer_info {
/* mesh_peer_instance as given in the spec. Note that, peer address
* is stored in scb
@ -275,6 +276,27 @@ typedef BWL_PRE_PACKED_STRUCT struct mesh_peer_info {
*/
} BWL_POST_PACKED_STRUCT mesh_peer_info_t;
typedef BWL_PRE_PACKED_STRUCT struct mesh_peer_info_ext {
mesh_peer_info_t peer_info;
uint16 local_aid; /* AID generated by *local* to peer */
struct ether_addr ea; /* peer ea */
uint32 entry_state; /* see MESH_PEER_ENTRY_STATE_ACTIVE etc; valid
* ONLY for internal peering requests
*/
int rssi;
} BWL_POST_PACKED_STRUCT mesh_peer_info_ext_t;
/* #ifdef WLMESH */
typedef BWL_PRE_PACKED_STRUCT struct mesh_peer_info_dump {
uint32 buflen;
uint32 version;
uint32 count; /* number of results */
mesh_peer_info_ext_t mpi_ext[1];
} BWL_POST_PACKED_STRUCT mesh_peer_info_dump_t;
#define WL_MESH_PEER_RES_FIXED_SIZE (sizeof(mesh_peer_info_dump_t) - sizeof(mesh_peer_info_ext_t))
#endif /* WLMESH */
/* once an entry is added into mesh_peer_list, if peering is lost, it will
* get retried for peering, MAX_MESH_PEER_ENTRY_RETRIES times. after wards, it
* wont get retried and will be moved to MESH_PEER_ENTRY_STATE_TIMEDOUT state,

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.9 (r)"
#define EPI_VERSION_STR "1.579.77.41.10 (r)"
#endif /* _epivers_h_ */

View File

@ -12416,31 +12416,6 @@ typedef enum {
#define WL_MESH_IOCTL_VERSION 1
#define MESH_IOC_BUFSZ 512 /* sufficient ioc buff size for mesh */
#ifdef WLMESH
typedef struct mesh_peer_info_ext {
mesh_peer_info_t peer_info;
uint8 pad1;
uint16 local_aid; /* AID generated by *local* to peer */
uint32 entry_state; /* see MESH_PEER_ENTRY_STATE_ACTIVE etc; valid
* ONLY for internal peering requests
*/
int8 rssi;
uint8 pad2;
struct ether_addr ea; /* peer ea */
} mesh_peer_info_ext_t;
/* #ifdef WLMESH */
typedef struct mesh_peer_info_dump {
uint32 buflen;
uint32 version;
uint16 count; /* number of results */
uint16 remaining; /* remaining rsults */
mesh_peer_info_ext_t mpi_ext[1];
} mesh_peer_info_dump_t;
#define WL_MESH_PEER_RES_FIXED_SIZE (sizeof(mesh_peer_info_dump_t) - sizeof(mesh_peer_info_ext_t))
#endif /* WLMESH */
/* container for mesh iovtls & events */
typedef struct wl_mesh_ioc {
uint16 version; /* interface command or event version */

View File

@ -33,6 +33,8 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <wldev_common.h>
#include <dngl_stats.h>
#include <dhd.h>
/* If any feature uses the Generic Netlink Interface, put it here to enable WL_GENL
* automatically
@ -67,6 +69,7 @@ typedef struct _compat_android_wifi_priv_cmd {
#define ANDROID_ERROR_LEVEL 0x0001
#define ANDROID_TRACE_LEVEL 0x0002
#define ANDROID_INFO_LEVEL 0x0004
#define ANDROID_EVENT_LEVEL 0x0008
#define ANDROID_ERROR(x) \
do { \
@ -89,6 +92,13 @@ typedef struct _compat_android_wifi_priv_cmd {
printk x; \
} \
} while (0)
#define ANDROID_EVENT(x) \
do { \
if (android_msg_level & ANDROID_EVENT_LEVEL) { \
printk(KERN_ERR "ANDROID-EVENT) "); \
printk x; \
} \
} while (0)
/**
* wl_android_init will be called from module init function (dhd_module_init now), similarly
@ -104,17 +114,26 @@ 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_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_attach_netdev(struct net_device *net, int ifidx, uint8 bssidx);
int wl_ext_iapsta_attach_name(struct net_device *net, int ifidx);
int wl_ext_iapsta_dettach_netdev(struct net_device *net, int ifidx);
u32 wl_ext_iapsta_update_channel(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);
int wl_ext_iapsta_attach(dhd_pub_t *pub);
void wl_ext_iapsta_dettach(dhd_pub_t *pub);
extern int op_mode;
#endif
int wl_android_ext_priv_cmd(struct net_device *net, char *command, int total_len,
int *bytes_written);
typedef struct wl_conn_info {
uint8 bssidx;
wlc_ssid_t ssid;
struct ether_addr bssid;
uint16 channel;
} wl_conn_info_t;
s32 wl_ext_connect(struct net_device *dev, wl_conn_info_t *conn_info);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
#define strnicmp(str1, str2, len) strncasecmp((str1), (str2), (len))
#endif
@ -231,6 +250,6 @@ int wl_ext_get_best_channel(struct net_device *net,
#else
struct wl_scan_results *bss_list,
#endif
int *best_2g_ch, int *best_5g_ch
int ioctl_ver, int *best_2g_ch, int *best_5g_ch
);
#endif /* _wl_android_ */

View File

@ -272,7 +272,7 @@ static const struct ieee80211_iface_limit common_if_limits[] = {
#else
#define NUM_DIFF_CHANNELS 2
#endif
static struct ieee80211_iface_combination
static const struct ieee80211_iface_combination
common_iface_combinations[] = {
{
.num_different_channels = NUM_DIFF_CHANNELS,
@ -912,6 +912,8 @@ extern int dhd_wait_pend8021x(struct net_device *dev);
#ifdef PROP_TXSTATUS_VSDB
extern int disable_proptx;
#endif /* PROP_TXSTATUS_VSDB */
static int wl_cfg80211_check_in4way(struct bcm_cfg80211 *cfg,
struct net_device *dev, uint action, enum wl_ext_status status, void *context);
extern int passive_channel_skip;
@ -1813,7 +1815,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy,
* requests.
*/
if ((cfg->p2p->p2p_go_count > 0) && (type == NL80211_IFTYPE_P2P_GO)) {
WL_ERR(("Fw doesnot support multiple Go"));
WL_ERR(("Fw does not support multiple Go\n"));
err = -ENOTSUPP;
goto fail;
}
@ -1831,7 +1833,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy,
cfg_type = wl_cfgp2p_get_conn_idx(cfg);
if (cfg_type == BCME_ERROR) {
wl_clr_p2p_status(cfg, IF_ADDING);
WL_ERR(("Failed to get connection idx for p2p interface"));
WL_ERR(("Failed to get connection idx for p2p interface\n"));
err = -ENOTSUPP;
goto fail;
}
@ -2296,7 +2298,7 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
*/
if ((cfg->p2p->p2p_go_count > 0) && (type == NL80211_IFTYPE_P2P_GO)) {
wl_set_mode_by_netdev(cfg, ndev, WL_MODE_BSS);
WL_ERR(("Fw doesnot support multiple GO "));
WL_ERR(("Fw does not support multiple GO\n"));
err = BCME_ERROR;
goto error;
}
@ -3354,6 +3356,10 @@ wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
return -ENODEV;
}
}
err = wl_cfg80211_check_in4way(cfg, ndev, NO_SCAN_IN4WAY,
WL_EXT_STATUS_SCAN, NULL);
if (err)
return err;
mutex_lock(&cfg->usr_sync);
err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
@ -3856,7 +3862,8 @@ wl_customer6_legacy_chip_check(struct bcm_cfg80211 *cfg,
dtoh32(revinfo.deviceid), dtoh32(revinfo.vendorid), dtoh32(revinfo.chipnum)));
chipnum = revinfo.chipnum;
if ((chipnum == BCM4350_CHIP_ID) || (chipnum == BCM4355_CHIP_ID) ||
(chipnum == BCM4345_CHIP_ID) || (chipnum == BCM43430_CHIP_ID)) {
(chipnum == BCM4345_CHIP_ID) || (chipnum == BCM43430_CHIP_ID) ||
(chipnum == BCM43362_CHIP_ID)) {
/* WAR required */
return true;
}
@ -3877,15 +3884,15 @@ wl_bss_iovar_war(struct bcm_cfg80211 *cfg,
memset(&revinfo, 0, sizeof(revinfo));
ret = wldev_ioctl_get(ndev, WLC_GET_REVINFO, &revinfo, sizeof(revinfo));
if (ret < 0) {
WL_ERR(("%s: GET revinfo FAILED. ret:%d\n", __FUNCTION__, ret));
WL_ERR(("%s: GET revinfo FAILED. ret:%d\n", __FUNCTION__, ret));
} else {
WL_DBG(("%s: GET_REVINFO device 0x%x, vendor 0x%x, chipnum 0x%x\n", __FUNCTION__,
dtoh32(revinfo.deviceid), dtoh32(revinfo.vendorid), dtoh32(revinfo.chipnum)));
chipnum = revinfo.chipnum;
if ((chipnum == BCM4359_CHIP_ID) || (chipnum == BCM43596_CHIP_ID)) {
/* WAR required */
need_war = true;
}
WL_DBG(("%s: GET_REVINFO device 0x%x, vendor 0x%x, chipnum 0x%x\n", __FUNCTION__,
dtoh32(revinfo.deviceid), dtoh32(revinfo.vendorid), dtoh32(revinfo.chipnum)));
chipnum = revinfo.chipnum;
if ((chipnum == BCM4359_CHIP_ID) || (chipnum == BCM43596_CHIP_ID)) {
/* WAR required */
need_war = true;
}
}
if (wl_customer6_legacy_chip_check(cfg, ndev) || need_war) {
@ -4158,8 +4165,8 @@ wl_cfg80211_post_ifcreate(struct net_device *ndev,
addr, ETH_ALEN, cfg->ioctl_buf, WLC_IOCTL_MAXLEN,
event->bssidx, &cfg->ioctl_buf_sync);
if (unlikely(ret)) {
WL_ERR(("set cur_etheraddr Error (%d)\n", ret));
goto fail;
WL_ERR(("set cur_etheraddr Error (%d)\n", ret));
goto fail;
}
memcpy(new_ndev->dev_addr, addr, ETH_ALEN);
WL_ERR(("Applying updated mac address to firmware\n"));
@ -5472,6 +5479,8 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
err = wl_cfg80211_cleanup_mismatch_status(dev, cfg, TRUE);
}
}
wl_cfg80211_check_in4way(cfg, dev, WAIT_DISCONNECTED,
WL_EXT_STATUS_CONNECTING, NULL);
/* 'connect' request received */
wl_set_drv_status(cfg, CONNECTING, dev);
@ -5653,7 +5662,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
DHD_DISABLE_RUNTIME_PM((dhd_pub_t *)cfg->pub);
#endif /* BCMDONGLEHOST && CUSTOMER_HW2 */
#ifdef WL_EXT_IAPSTA
wl_ext_iapsta_disconnect_sta(dev, cfg->channel);
wl_ext_iapsta_update_channel(dev, cfg->channel);
#endif
err = wldev_iovar_setbuf_bsscfg(dev, "join", ext_join_params, join_params_size,
cfg->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &cfg->ioctl_buf_sync);
@ -5711,6 +5720,9 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
WL_ERR(("error (%d)\n", err));
wl_clr_drv_status(cfg, CONNECTING, dev);
}
if (!err)
wl_cfg80211_check_in4way(cfg, dev, NO_SCAN_IN4WAY|NO_BTC_IN4WAY,
WL_EXT_STATUS_CONNECTING, NULL);
#ifdef WLTDLS
/* disable TDLS if number of connected interfaces is >= 1 */
@ -5795,6 +5807,8 @@ wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
WL_ERR(("error (%d)\n", err));
return err;
}
wl_cfg80211_check_in4way(cfg, dev, NO_SCAN_IN4WAY|NO_BTC_IN4WAY|WAIT_DISCONNECTED,
WL_EXT_STATUS_DISCONNECTING, NULL);
wl_cfg80211_wait_for_disconnection(cfg, dev);
}
}
@ -6155,6 +6169,7 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
s32 bssidx = 0;
struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
s32 mode = wl_get_mode_by_netdev(cfg, dev);
WL_DBG(("key index (%d)\n", key_idx));
RETURN_EIO_IF_NOT_UP(cfg);
@ -6259,6 +6274,8 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
WL_ERR(("set wsec error (%d)\n", err));
return err;
}
wl_cfg80211_check_in4way(cfg, dev, NO_SCAN_IN4WAY|NO_BTC_IN4WAY,
WL_EXT_STATUS_ADD_KEY, NULL);
return err;
}
@ -8052,7 +8069,7 @@ wl_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
dev = ndev_to_wlc_ndev(dev, cfg);
_chan = ieee80211_frequency_to_channel(chan->center_freq);
#ifdef WL_EXT_IAPSTA
_chan = wl_ext_iapsta_disconnect_sta(dev, _chan);
_chan = wl_ext_iapsta_update_channel(dev, _chan);
#endif
printf("%s: netdev_ifidx(%d), chan_type(%d) target channel(%d) \n",
__FUNCTION__, dev->ifindex, channel_type, _chan);
@ -9164,7 +9181,6 @@ wl_cfg80211_bcn_bringup_ap(
WL_ERR(("failed to disable uapsd, error=%d\n", err));
}
#endif /* SOFTAP_UAPSD_OFF */
dhd_conf_set_wme(cfg->pub, 1);
err = wldev_ioctl_set(dev, WLC_UP, &ap, sizeof(s32));
if (unlikely(err)) {
@ -9200,6 +9216,14 @@ wl_cfg80211_bcn_bringup_ap(
WL_ERR(("Could not get wsec %d\n", err));
goto exit;
}
if (dhdp->conf->chip == BCM43430_CHIP_ID && bssidx > 0 && wsec >= 2) {
wsec |= 0x8; // terence 20180628: fix me, this is a workaround
err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
if (err < 0) {
WL_ERR(("wsec error %d\n", err));
goto exit;
}
}
if ((wsec == WEP_ENABLED) && cfg->wep_key.len) {
WL_DBG(("Applying buffered WEP KEY \n"));
err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &cfg->wep_key,
@ -9244,7 +9268,7 @@ wl_cfg80211_bcn_bringup_ap(
/* create softap */
if ((err = wldev_ioctl_set(dev, WLC_SET_SSID, &join_params,
join_params_size)) != 0) {
WL_ERR(("SoftAP/GO set ssid failed! \n"));
WL_ERR(("SoftAP/GO set ssid failed! %d\n", err));
goto exit;
} else {
WL_DBG((" SoftAP SSID \"%s\" \n", join_params.ssid.SSID));
@ -9519,6 +9543,7 @@ wl_cfg80211_del_station(
u16 rc = params->reason_code;
#endif /* CUSTOM_BLOCK_DEAUTH_AT_EAP_FAILURE */
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) */
WL_DBG(("Entry\n"));
if (mac_addr == NULL) {
WL_DBG(("mac_addr is NULL ignore it\n"));
@ -9536,6 +9561,11 @@ wl_cfg80211_del_station(
return -EFAULT;
}
}
err = wl_cfg80211_check_in4way(cfg, ndev, DONT_DELETE_GC_AFTER_WPS,
WL_EXT_STATUS_DELETE_STA, (void *)mac_addr);
if (err) {
return 0;
}
assoc_maclist->count = MAX_NUM_OF_ASSOCIATED_DEV;
err = wldev_ioctl_get(ndev, WLC_GET_ASSOCLIST,
@ -9947,6 +9977,10 @@ wl_cfg80211_stop_ap(
#endif /* ARP_OFFLOAD_SUPPORT */
if (is_rsdb_supported == 0) {
if (dhd_download_fw_on_driverload && bssidx == 0) {
wldev_ioctl_set(dev, WLC_DOWN, &ap, sizeof(s32));
wldev_iovar_setint(dev, "apsta", 1);
}
/* For non-rsdb chips, we use stand alone AP. Do wl down on stop AP */
err = wldev_ioctl_set(dev, WLC_UP, &ap, sizeof(s32));
if (unlikely(err)) {
@ -10908,10 +10942,6 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) && \
(defined(WL_IFACE_COMB_NUM_CHANNELS) || defined(WL_CFG80211_P2P_DEV_IF))
WL_DBG(("Setting interface combinations for common mode\n"));
#ifndef BCMDBUS
if (dhd->conf->num_different_channels >= 0)
common_iface_combinations[0].num_different_channels = dhd->conf->num_different_channels;
#endif /* !BCMDBUS */
wdev->wiphy->iface_combinations = common_iface_combinations;
wdev->wiphy->n_iface_combinations =
ARRAY_SIZE(common_iface_combinations);
@ -11169,7 +11199,8 @@ static s32 wl_inform_bss(struct bcm_cfg80211 *cfg)
node = node->next;
}
if (cfg->autochannel)
wl_ext_get_best_channel(ndev, &cfg->g_bss_cache_ctrl, &cfg->best_2g_ch, &cfg->best_5g_ch);
wl_ext_get_best_channel(ndev, &cfg->g_bss_cache_ctrl, ioctl_version,
&cfg->best_2g_ch, &cfg->best_5g_ch);
#else
WL_SCAN(("scanned AP count (%d)\n", bss_list->count));
preempt_disable();
@ -11181,7 +11212,8 @@ static s32 wl_inform_bss(struct bcm_cfg80211 *cfg)
}
preempt_enable();
if (cfg->autochannel)
wl_ext_get_best_channel(ndev, bss_list, &cfg->best_2g_ch, &cfg->best_5g_ch);
wl_ext_get_best_channel(ndev, bss_list, ioctl_version,
&cfg->best_2g_ch, &cfg->best_5g_ch);
#endif
if (cfg->p2p_disconnected > 0) {
@ -11556,9 +11588,7 @@ wl_notify_connect_status_ap(struct bcm_cfg80211 *cfg, struct net_device *ndev,
printf("%s: ** AP/GO Link up event **\n", __FUNCTION__);
wl_set_drv_status(cfg, AP_CREATED, ndev);
wake_up_interruptible(&cfg->netif_change_event);
if (!memcmp(ndev->name, WL_P2P_INTERFACE_PREFIX, strlen(WL_P2P_INTERFACE_PREFIX))) {
dhd_conf_set_mchan_bw(cfg->pub, WL_P2P_IF_GO, -1);
}
wl_cfg80211_check_in4way(cfg, ndev, 0, WL_EXT_STATUS_AP_ENABLED, NULL);
return 0;
}
}
@ -11683,13 +11713,19 @@ wl_notify_connect_status_ap(struct bcm_cfg80211 *cfg, struct net_device *ndev,
sinfo.assoc_req_ies = data;
sinfo.assoc_req_ies_len = len;
printf("%s: connected device "MACDBG"\n", __FUNCTION__, MAC2STRDBG(e->addr.octet));
wl_cfg80211_check_in4way(cfg, ndev, DONT_DELETE_GC_AFTER_WPS,
WL_EXT_STATUS_STA_CONNECTED, NULL);
cfg80211_new_sta(ndev, e->addr.octet, &sinfo, GFP_ATOMIC);
} else if (event == WLC_E_DISASSOC_IND) {
printf("%s: disassociated device "MACDBG"\n", __FUNCTION__, MAC2STRDBG(e->addr.octet));
wl_cfg80211_check_in4way(cfg, ndev, DONT_DELETE_GC_AFTER_WPS,
WL_EXT_STATUS_STA_DISCONNECTED, NULL);
cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC);
} else if ((event == WLC_E_DEAUTH_IND) ||
((event == WLC_E_DEAUTH) && (reason != DOT11_RC_RESERVED))) {
printf("%s: deauthenticated device "MACDBG"\n", __FUNCTION__, MAC2STRDBG(e->addr.octet));
wl_cfg80211_check_in4way(cfg, ndev, DONT_DELETE_GC_AFTER_WPS,
WL_EXT_STATUS_STA_DISCONNECTED, NULL);
cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC);
}
#endif
@ -12194,7 +12230,6 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
vndr_oui_num > 0 ? vndr_oui : "");
wl_bss_connect_done(cfg, ndev, e, data, true);
dhd_conf_set_intiovar(cfg->pub, WLC_SET_VAR, "phy_oclscdenable", cfg->pub->conf->phy_oclscdenable, 0, FALSE);
WL_DBG(("joined in BSS network \"%s\"\n",
((struct wlc_ssid *)
wl_read_prof(cfg, ndev, WL_PROF_SSID))->SSID));
@ -12212,10 +12247,6 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
}
wl_update_prof(cfg, ndev, e, &act, WL_PROF_ACT);
wl_update_prof(cfg, ndev, NULL, (const void *)&e->addr, WL_PROF_BSSID);
dhd_conf_set_wme(cfg->pub, 0);
if (!memcmp(ndev->name, WL_P2P_INTERFACE_PREFIX, strlen(WL_P2P_INTERFACE_PREFIX))) {
dhd_conf_set_mchan_bw(cfg->pub, WL_P2P_IF_CLIENT, -1);
}
} else if (WL_IS_LINKDOWN(cfg, e, data) ||
((event == WLC_E_SET_SSID) &&
(ntoh32(e->status) != WLC_E_STATUS_SUCCESS) &&
@ -12236,6 +12267,8 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
* the event to avoid pre-empting the current connection
*/
WL_INFORM(("Nested connection case. Drop event. \n"));
wl_cfg80211_check_in4way(cfg, ndev, NO_SCAN_IN4WAY|NO_BTC_IN4WAY|WAIT_DISCONNECTED,
WL_EXT_STATUS_DISCONNECTED, NULL);
wl_clr_drv_status(cfg, NESTED_CONNECT, ndev);
wl_clr_drv_status(cfg, DISCONNECTING, ndev);
/* Not in 'CONNECTED' state, clear it */
@ -12357,11 +12390,6 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
// terence 20130703: Fix for wrong group_capab (timing issue)
cfg->p2p_disconnected = 1;
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
if (wl_get_drv_status(cfg, DISCONNECTING, ndev)) {
CFG80211_DISCONNECTED(ndev, reason, NULL, 0, false, GFP_KERNEL);
}
#endif
memcpy(&cfg->disconnected_bssid, curbssid, ETHER_ADDR_LEN);
wl_clr_drv_status(cfg, CONNECTED, ndev);
@ -12433,6 +12461,8 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
wl_bss_connect_done(cfg, ndev, e, data, false);
}
wl_clr_drv_status(cfg, DISCONNECTING, ndev);
wl_cfg80211_check_in4way(cfg, ndev, NO_SCAN_IN4WAY|NO_BTC_IN4WAY|WAIT_DISCONNECTED,
WL_EXT_STATUS_DISCONNECTED, NULL);
/* if link down, bsscfg is diabled */
if (ndev != bcmcfg_to_prmry_ndev(cfg))
@ -12446,6 +12476,8 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
} else if (wl_is_nonetwork(cfg, e)) {
printf("connect failed event=%d e->status %d e->reason %d \n",
event, (int)ntoh32(e->status), (int)ntoh32(e->reason));
wl_cfg80211_check_in4way(cfg, ndev, NO_SCAN_IN4WAY|NO_BTC_IN4WAY|WAIT_DISCONNECTED,
WL_EXT_STATUS_DISCONNECTED, NULL);
#if defined(DHD_ENABLE_BIGDATA_LOGGING)
if (event == WLC_E_SET_SSID) {
wl_get_connect_failed_status(cfg, e);
@ -13135,7 +13167,7 @@ wl_bss_roaming_done(struct bcm_cfg80211 *cfg, struct net_device *ndev,
#endif /* WLADPS_SEAK_AP_WAR */
printf("%s succeeded to " MACDBG " (ch:%d)\n", __FUNCTION__,
MAC2STRDBG((const u8*)(&e->addr)), *channel);
dhd_conf_set_wme(cfg->pub, 0);
wl_cfg80211_check_in4way(cfg, ndev, 0, WL_EXT_STATUS_CONNECTED, NULL);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
roam_info.channel = notify_channel;
@ -13307,6 +13339,9 @@ wl_bss_connect_done(struct bcm_cfg80211 *cfg, struct net_device *ndev,
completed = false;
sec->auth_assoc_res_status = WLAN_STATUS_UNSPECIFIED_FAILURE;
}
if (completed) {
wl_cfg80211_check_in4way(cfg, ndev, 0, WL_EXT_STATUS_CONNECTED, NULL);
}
cfg80211_connect_result(ndev,
curbssid,
conn_info->req_ie,
@ -13320,9 +13355,11 @@ wl_bss_connect_done(struct bcm_cfg80211 *cfg, struct net_device *ndev,
GFP_KERNEL);
if (completed) {
WL_INFORM(("Report connect result - connection succeeded\n"));
dhd_conf_set_wme(cfg->pub, 0);
} else
} else {
WL_ERR(("Report connect result - connection failed\n"));
wl_cfg80211_check_in4way(cfg, ndev, NO_SCAN_IN4WAY|NO_BTC_IN4WAY|WAIT_DISCONNECTED,
WL_EXT_STATUS_DISCONNECTED, NULL);
}
}
#ifdef CONFIG_TCPACK_FASTTX
if (wl_get_chan_isvht80(ndev, dhdp))
@ -15050,6 +15087,7 @@ static s32 wl_escan_without_scan_cache(struct bcm_cfg80211 *cfg, wl_escan_result
}
#endif /* WL_DRV_AVOID_SCANCACHE */
static s32 wl_escan_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
const wl_event_msg_t *e, void *data)
{
@ -15203,7 +15241,7 @@ static s32 wl_escan_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
goto exit;
}
#ifdef ESCAN_BUF_OVERFLOW_MGMT
WL_TRACE(("%s("MACDBG"), i=%d bss: RSSI %d list->count %d\n",
WL_SCAN(("%s("MACDBG"), i=%d bss: RSSI %d list->count %d\n",
bss->SSID, MAC2STRDBG(bss->BSSID.octet),
i, bss->RSSI, list->count));
@ -15333,7 +15371,7 @@ static s32 wl_escan_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
DBG_EVENT_LOG((dhd_pub_t *)cfg->pub, WIFI_EVENT_DRIVER_SCAN_COMPLETE);
cfg->bss_list = wl_escan_get_buf(cfg, FALSE);
if (!scan_req_match(cfg)) {
WL_TRACE_HW4(("SCAN COMPLETED: scanned AP count=%d\n",
WL_SCAN(("SCAN COMPLETED: scanned AP count=%d\n",
cfg->bss_list->count));
}
wl_inform_bss(cfg);
@ -15605,6 +15643,7 @@ static s32 wl_notifier_change_state(struct bcm_cfg80211 *cfg, struct net_info *_
}
return err;
}
static s32 wl_init_scan(struct bcm_cfg80211 *cfg)
{
int err = 0;
@ -15669,6 +15708,7 @@ static s32 wl_init_priv(struct bcm_cfg80211 *cfg)
spin_lock_init(&cfg->cfgdrv_lock);
mutex_init(&cfg->ioctl_buf_sync);
init_waitqueue_head(&cfg->netif_change_event);
init_waitqueue_head(&cfg->wps_done_event);
init_completion(&cfg->send_af_done);
init_completion(&cfg->iface_disable);
mutex_init(&cfg->usr_sync);
@ -15676,6 +15716,7 @@ static s32 wl_init_priv(struct bcm_cfg80211 *cfg)
mutex_init(&cfg->scan_complete);
mutex_init(&cfg->if_sync);
mutex_init(&cfg->pm_sync);
mutex_init(&cfg->in4way_sync);
#ifdef WLTDLS
mutex_init(&cfg->tdls_sync);
#endif /* WLTDLS */
@ -17008,6 +17049,8 @@ s32 wl_cfg80211_up(struct net_device *net)
}
ioctl_version = val;
WL_TRACE(("WLC_GET_VERSION=%d\n", ioctl_version));
wl_cfg80211_check_in4way(cfg, net, NO_SCAN_IN4WAY|NO_BTC_IN4WAY|WAIT_DISCONNECTED,
WL_EXT_STATUS_DISCONNECTED, NULL);
mutex_lock(&cfg->usr_sync);
dhd = (dhd_pub_t *)(cfg->pub);
@ -21676,7 +21719,8 @@ wl_set_rssi_logging(struct net_device *dev, void *param)
}
#endif /* SUPPORT_RSSI_LOGGING */
s32 wl_cfg80211_autochannel(struct net_device *dev, char* command, int total_len)
s32
wl_cfg80211_autochannel(struct net_device *dev, char* command, int total_len)
{
struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
int ret = 0;
@ -21696,3 +21740,200 @@ s32 wl_cfg80211_autochannel(struct net_device *dev, char* command, int total_len
return ret;
}
static int
wl_cfg80211_check_in4way(struct bcm_cfg80211 *cfg,
struct net_device *dev, uint action, enum wl_ext_status status, void *context)
{
dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
struct wl_security *sec;
s32 bssidx = -1;
int ret = 0, cur_eapol_status;
int max_wait_time, max_wait_cnt;
mutex_lock(&cfg->in4way_sync);
WL_DBG(("status=%d, action=0x%x\n", status, action));
cur_eapol_status = dhdp->conf->eapol_status;
switch (status) {
case WL_EXT_STATUS_SCAN:
if (action & NO_SCAN_IN4WAY) {
if (cfg->handshaking > 0 && cfg->handshaking <= 3) {
WL_ERR(("return -EBUSY cnt %d\n", cfg->handshaking));
cfg->handshaking++;
ret = -EBUSY;
break;
}
}
break;
case WL_EXT_STATUS_DISCONNECTING:
if (cur_eapol_status >= EAPOL_STATUS_WPA_START &&
cur_eapol_status < EAPOL_STATUS_WPA_END) {
ANDROID_ERROR(("%s: WPA failed at %d\n", __FUNCTION__,
cur_eapol_status));
dhdp->conf->eapol_status = EAPOL_STATUS_NONE;
} else if (cur_eapol_status >= EAPOL_STATUS_WPS_WSC_START &&
cur_eapol_status < EAPOL_STATUS_WPS_DONE) {
ANDROID_ERROR(("%s: WPS failed at %d\n", __FUNCTION__,
cur_eapol_status));
dhdp->conf->eapol_status = EAPOL_STATUS_NONE;
}
if (action & (NO_SCAN_IN4WAY|NO_BTC_IN4WAY)) {
if (cfg->handshaking) {
if (action & NO_BTC_IN4WAY) {
WL_TRACE(("status=%d, enable btc_mode\n", status));
wldev_iovar_setint(dev, "btc_mode", 1);
}
cfg->handshaking = 0;
}
}
if (action & WAIT_DISCONNECTED) {
max_wait_time = 200;
max_wait_cnt = 20;
cfg->disconnected_jiffies = jiffies;
while (!time_after(jiffies,
cfg->disconnected_jiffies + msecs_to_jiffies(max_wait_time)) &&
max_wait_cnt) {
WL_TRACE(("status=%d, max_wait_cnt=%d waiting...\n",
status, max_wait_cnt));
mutex_unlock(&cfg->in4way_sync);
OSL_SLEEP(50);
mutex_lock(&cfg->in4way_sync);
max_wait_cnt--;
}
}
break;
case WL_EXT_STATUS_CONNECTING:
if (action & (NO_SCAN_IN4WAY|NO_BTC_IN4WAY)) {
bssidx = wl_get_bssidx_by_wdev(cfg, dev->ieee80211_ptr);
sec = wl_read_prof(cfg, dev, WL_PROF_SEC);
if ((sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) &&
bssidx == 0) {
dhdp->conf->eapol_status = EAPOL_STATUS_WPA_START;
cfg->handshaking = 1;
if (action & NO_BTC_IN4WAY) {
WL_TRACE(("status=%d, disable btc_mode\n", status));
wldev_iovar_setint(dev, "btc_mode", 0);
}
}
}
if (action & WAIT_DISCONNECTED) {
max_wait_time = 200;
max_wait_cnt = 10;
while (!time_after(jiffies,
cfg->disconnected_jiffies + msecs_to_jiffies(max_wait_time)) &&
max_wait_cnt) {
WL_TRACE(("status=%d, max_wait_cnt=%d waiting...\n",
status, max_wait_cnt));
mutex_unlock(&cfg->in4way_sync);
OSL_SLEEP(50);
mutex_lock(&cfg->in4way_sync);
max_wait_cnt--;
}
}
break;
case WL_EXT_STATUS_CONNECTED:
if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_STATION) {
dhd_conf_set_wme(cfg->pub, 0);
dhd_conf_set_intiovar(cfg->pub, WLC_SET_VAR, "phy_oclscdenable",
cfg->pub->conf->phy_oclscdenable, 0, FALSE);
}
else if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_CLIENT) {
dhd_conf_set_mchan_bw(cfg->pub, WL_P2P_IF_CLIENT, -1);
}
break;
case WL_EXT_STATUS_DISCONNECTED:
if (cur_eapol_status >= EAPOL_STATUS_WPA_START &&
cur_eapol_status < EAPOL_STATUS_WPA_END) {
ANDROID_ERROR(("%s: WPA failed at %d\n", __FUNCTION__, cur_eapol_status));
dhdp->conf->eapol_status = EAPOL_STATUS_NONE;
} else if (cur_eapol_status >= EAPOL_STATUS_WPS_WSC_START &&
cur_eapol_status < EAPOL_STATUS_WPS_DONE) {
ANDROID_ERROR(("%s: WPS failed at %d\n", __FUNCTION__, cur_eapol_status));
dhdp->conf->eapol_status = EAPOL_STATUS_NONE;
}
if (action & (NO_SCAN_IN4WAY|NO_BTC_IN4WAY)) {
if (cfg->handshaking) {
if (action & NO_BTC_IN4WAY) {
WL_TRACE(("status=%d, enable btc_mode\n", status));
wldev_iovar_setint(dev, "btc_mode", 1);
}
cfg->handshaking = 0;
}
}
if (action & WAIT_DISCONNECTED) {
cfg->disconnected_jiffies = jiffies;
}
break;
case WL_EXT_STATUS_ADD_KEY:
dhdp->conf->eapol_status = EAPOL_STATUS_WPA_END;
if (action & (NO_SCAN_IN4WAY|NO_BTC_IN4WAY)) {
if (cfg->handshaking) {
if (action & NO_BTC_IN4WAY) {
WL_TRACE(("status=%d, enable btc_mode\n", status));
wldev_iovar_setint(dev, "btc_mode", 1);
}
cfg->handshaking = 0;
}
}
break;
case WL_EXT_STATUS_AP_ENABLED:
if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP) {
dhd_conf_set_wme(cfg->pub, 1);
}
else if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO) {
dhd_conf_set_mchan_bw(cfg->pub, WL_P2P_IF_GO, -1);
}
break;
case WL_EXT_STATUS_DELETE_STA:
if ((action & DONT_DELETE_GC_AFTER_WPS) &&
(dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO)) {
u8* mac_addr = context;
if (mac_addr && memcmp(&ether_bcast, mac_addr, ETHER_ADDR_LEN) &&
cur_eapol_status == EAPOL_STATUS_WPS_DONE) {
u32 timeout;
max_wait_time = dhdp->conf->max_wait_gc_time;
WL_TRACE(("status=%d, wps_done=%d, waiting %dms ...\n",
status, cfg->wps_done, max_wait_time));
mutex_unlock(&cfg->in4way_sync);
timeout = wait_event_interruptible_timeout(cfg->wps_done_event,
cfg->wps_done, msecs_to_jiffies(max_wait_time));
mutex_lock(&cfg->in4way_sync);
WL_TRACE(("status=%d, wps_done=%d, timeout=%d\n",
status, cfg->wps_done, timeout));
if (timeout > 0) {
ret = -1;
break;
}
} else {
WL_TRACE(("status=%d, wps_done=%d => 0\n", status, cfg->wps_done));
cfg->wps_done = FALSE;
dhdp->conf->eapol_status = EAPOL_STATUS_NONE;
}
}
break;
case WL_EXT_STATUS_STA_DISCONNECTED:
if ((action & DONT_DELETE_GC_AFTER_WPS) &&
(dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO) &&
cur_eapol_status == EAPOL_STATUS_WPS_DONE) {
WL_TRACE(("status=%d, wps_done=%d => 0\n", status, cfg->wps_done));
cfg->wps_done = FALSE;
}
break;
case WL_EXT_STATUS_STA_CONNECTED:
if ((action & DONT_DELETE_GC_AFTER_WPS) &&
(dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO) &&
cur_eapol_status == EAPOL_STATUS_WPS_DONE) {
WL_TRACE(("status=%d, wps_done=%d => 1\n", status, cfg->wps_done));
cfg->wps_done = TRUE;
wake_up_interruptible(&cfg->wps_done_event);
}
break;
default:
WL_ERR(("Unknown action=0x%x, status=%d\n", action, status));
}
mutex_unlock(&cfg->in4way_sync);
return ret;
}

View File

@ -341,6 +341,20 @@ enum wl_status {
WL_STATUS_NESTED_CONNECT
};
enum wl_ext_status {
WL_EXT_STATUS_DISCONNECTING = 0,
WL_EXT_STATUS_DISCONNECTED,
WL_EXT_STATUS_SCAN,
WL_EXT_STATUS_CONNECTING,
WL_EXT_STATUS_CONNECTED,
WL_EXT_STATUS_ADD_KEY,
WL_EXT_STATUS_AP_ENABLED,
WL_EXT_STATUS_DELETE_STA,
WL_EXT_STATUS_STA_DISCONNECTED,
WL_EXT_STATUS_STA_CONNECTED,
WL_EXT_STATUS_AP_DISABLED
};
/* wi-fi mode */
enum wl_mode {
WL_MODE_BSS,
@ -871,6 +885,11 @@ struct bcm_cfg80211 {
int autochannel;
int best_2g_ch;
int best_5g_ch;
uint handshaking;
bool wps_done;
wait_queue_head_t wps_done_event;
struct mutex in4way_sync;
ulong disconnected_jiffies;
};
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \

View File

@ -54,6 +54,7 @@
#define dtoh16(i) (i)
#define htodchanspec(i) (i)
#define dtohchanspec(i) (i)
#define WL_EXTRA_BUF_MAX 2048
#define wl_escan_get_buf(a) ((wl_scan_results_t *) (a)->escan_buf)
@ -71,7 +72,6 @@ typedef struct {
} removal_element_t;
#endif /* ESCAN_BUF_OVERFLOW_MGMT */
struct wl_escan_info *g_escan = NULL;
/* Return a new chanspec given a legacy chanspec
* Returns INVCHANSPEC on error
*/
@ -179,9 +179,9 @@ wl_chspec_driver_to_host(int ioctl_ver, chanspec_t chanspec)
* Returns INVCHANSPEC on error
*/
static chanspec_t
wl_chspec_host_to_driver(chanspec_t chanspec)
wl_chspec_host_to_driver(int ioctl_ver, chanspec_t chanspec)
{
if (1) {
if (ioctl_ver == 1) {
chanspec = wl_chspec_to_legacy(chanspec);
if (chanspec == INVCHANSPEC) {
return chanspec;
@ -197,7 +197,7 @@ wl_chspec_host_to_driver(chanspec_t chanspec)
* Returns INVCHANSPEC on error
*/
static chanspec_t
wl_ch_host_to_driver(s32 bssidx, u16 channel)
wl_ch_host_to_driver(int ioctl_ver, s32 bssidx, u16 channel)
{
chanspec_t chanspec;
@ -212,7 +212,7 @@ wl_ch_host_to_driver(s32 bssidx, u16 channel)
chanspec |= WL_CHANSPEC_CTL_SB_NONE;
return wl_chspec_host_to_driver(chanspec);
return wl_chspec_host_to_driver(ioctl_ver, chanspec);
}
static inline struct wl_bss_info *next_bss(struct wl_scan_results *list, struct wl_bss_info *bss)
@ -408,8 +408,9 @@ static s32 wl_escan_event_handler(void *data)
void
wl_escan_event(struct net_device *dev, const wl_event_msg_t * e, void *data)
{
struct dhd_pub *dhd = dhd_get_pub(dev);
struct wl_escan_info *escan = dhd->escan;
u32 event_type = ntoh32(e->event_type);
struct wl_escan_info *escan = g_escan;
if (!escan || !escan->dev) {
return;
@ -481,10 +482,12 @@ static s32 wl_escan_inform_bss(struct wl_escan_info *escan)
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);
wl_ext_get_best_channel(escan->dev, &escan->g_bss_cache_ctrl,
escan->ioctl_ver &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);
wl_ext_get_best_channel(escan->dev, bss_list, escan->ioctl_ver,
&escan->best_2g_ch, &escan->best_5g_ch);
#endif
ESCAN_TRACE(("scanned AP count (%d)\n", bss_list->count));
@ -493,7 +496,8 @@ static s32 wl_escan_inform_bss(struct wl_escan_info *escan)
}
static wl_scan_params_t *
wl_escan_alloc_params(int channel, int nprobes, int *out_params_size)
wl_escan_alloc_params(struct wl_escan_info *escan, int channel,
int nprobes, int *out_params_size)
{
wl_scan_params_t *params;
int params_size;
@ -524,7 +528,7 @@ wl_escan_alloc_params(int channel, int nprobes, int *out_params_size)
if (channel == -1)
params->channel_list[0] = htodchanspec(channel);
else
params->channel_list[0] = wl_ch_host_to_driver(bssidx, channel);
params->channel_list[0] = wl_ch_host_to_driver(escan->ioctl_ver, bssidx, channel);
/* Our scan params have 1 channel and 0 ssids */
params->channel_num = htod32((0 << WL_SCAN_PARAMS_NSSID_SHIFT) |
@ -541,7 +545,7 @@ static void wl_escan_abort(struct wl_escan_info *escan)
s32 err = BCME_OK;
if (!in_atomic()) {
/* Our scan params only need space for 1 channel and 0 ssids */
params = wl_escan_alloc_params(-1, 0, &params_size);
params = wl_escan_alloc_params(escan, -1, 0, &params_size);
if (params == NULL) {
ESCAN_ERROR(("scan params allocation failed \n"));
err = -ENOMEM;
@ -942,7 +946,8 @@ wl_escan_prep(struct wl_escan_info *escan, wl_uint32_list_t *list,
params->channel_list[j] |= chanspec;
ESCAN_SCAN(("Chan : %d, Channel spec: %x \n",
channel, params->channel_list[j]));
params->channel_list[j] = wl_chspec_host_to_driver(params->channel_list[j]);
params->channel_list[j] = wl_chspec_host_to_driver(escan->ioctl_ver,
params->channel_list[j]);
j++;
}
} else {
@ -1048,12 +1053,13 @@ wl_escan_set_scan(
char *extra
)
{
struct dhd_pub *dhd = dhd_get_pub(dev);
struct wl_escan_info *escan = dhd->escan;
s32 err = BCME_OK;
s32 params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_escan_params_t, params));
wl_escan_params_t *params = NULL;
scb_val_t scbval;
static int cnt = 0;
struct wl_escan_info *escan = g_escan;
wlc_ssid_t ssid;
u32 n_channels = 0;
wl_uint32_list_t *list;
@ -1144,6 +1150,7 @@ wl_escan_set_scan(
err = wldev_iovar_setbuf(dev, "escan", params, params_size,
escan->escan_ioctl_buf, WLC_IOCTL_MEDLEN, NULL);
printf("%s: LEGACY_SCAN\n", __FUNCTION__);
if (unlikely(err)) {
if (err == BCME_EPERM)
/* Scan Not permitted at this point of time */
@ -1178,25 +1185,133 @@ wl_escan_set_scan(
}
int
wl_escan_get_scan(
struct net_device *dev,
struct iw_request_info *info,
struct iw_point *dwrq,
char *extra
)
wl_escan_merge_scan_results(struct net_device *dev, struct iw_request_info *info,
char *extra, wl_bss_info_t *bi, int *len, int max_size)
{
struct dhd_pub *dhd = dhd_get_pub(dev);
struct wl_escan_info *escan = dhd->escan;
s32 err = BCME_OK;
struct iw_event iwe;
int i, j;
char *event = extra, *end = extra + dwrq->length, *value;
int j;
char *event = extra, *end = extra + max_size - WE_ADD_EVENT_FIX, *value;
int16 rssi;
int channel;
/* overflow check cover fields before wpa IEs */
if (event + ETHER_ADDR_LEN + bi->SSID_len + IW_EV_UINT_LEN + IW_EV_FREQ_LEN +
IW_EV_QUAL_LEN >= end) {
err = -E2BIG;
goto exit;
}
#if defined(RSSIAVG)
rssi = wl_get_avg_rssi(&escan->g_rssi_cache_ctrl, &bi->BSSID);
if (rssi == RSSI_MINVAL)
rssi = MIN(dtoh16(bi->RSSI), RSSI_MAXVAL);
#else
// terence 20150419: limit the max. rssi to -2 or the bss will be filtered out in android OS
rssi = MIN(dtoh16(bi->RSSI), RSSI_MAXVAL);
#endif
channel = wf_chspec_ctlchan(wl_chspec_driver_to_host(escan->ioctl_ver, bi->chanspec));
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;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN);
event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN);
/* SSID */
iwe.u.data.length = dtoh32(bi->SSID_len);
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID);
/* Mode */
if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) {
iwe.cmd = SIOCGIWMODE;
if (dtoh16(bi->capability) & DOT11_CAP_ESS)
iwe.u.mode = IW_MODE_INFRA;
else
iwe.u.mode = IW_MODE_ADHOC;
event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_UINT_LEN);
}
/* Channel */
iwe.cmd = SIOCGIWFREQ;
#if 1
iwe.u.freq.m = wf_channel2mhz(channel, channel <= CH_MAX_2G_CHANNEL ?
WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G);
#else
iwe.u.freq.m = wf_channel2mhz(bi->n_cap ?
bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec),
CHSPEC_CHANNEL(bi->chanspec) <= CH_MAX_2G_CHANNEL ?
WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G);
#endif
iwe.u.freq.e = 6;
event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN);
/* Channel quality */
iwe.cmd = IWEVQUAL;
iwe.u.qual.qual = rssi_to_qual(rssi);
iwe.u.qual.level = 0x100 + rssi;
iwe.u.qual.noise = 0x100 + bi->phy_noise;
event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN);
wl_iw_handle_scanresults_ies(&event, end, info, bi);
/* Encryption */
iwe.cmd = SIOCGIWENCODE;
if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY)
iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event);
/* Rates */
if (bi->rateset.count <= sizeof(bi->rateset.rates)) {
if (event + IW_MAX_BITRATES*IW_EV_PARAM_LEN >= end) {
err = -E2BIG;
goto exit;
}
value = event + IW_EV_LCP_LEN;
iwe.cmd = SIOCGIWRATE;
/* Those two flags are ignored... */
iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) {
iwe.u.bitrate.value = (bi->rateset.rates[j] & 0x7f) * 500000;
value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe,
IW_EV_PARAM_LEN);
}
event = value;
}
*len = event - extra;
if (*len < 0)
ESCAN_ERROR(("==> Wrong size\n"));
exit:
return err;
}
int
wl_escan_get_scan(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
struct dhd_pub *dhd = dhd_get_pub(dev);
struct wl_escan_info *escan = dhd->escan;
s32 err = BCME_OK;
int i = 0;
int len_prep = 0, len_ret = 0;
wl_bss_info_t *bi = NULL;
struct wl_escan_info *escan = g_escan;
struct wl_scan_results *bss_list;
__u16 buflen_from_user = dwrq->length;
#if defined(BSSCACHE)
wl_bss_cache_t *node;
#endif
char *buf = NULL;
struct ether_addr cur_bssid;
ESCAN_TRACE(("%s: %s SIOCGIWSCAN, len=%d\n", __FUNCTION__, dev->name, dwrq->length));
@ -1217,6 +1332,31 @@ wl_escan_get_scan(
goto exit;
}
err = wldev_ioctl(dev, WLC_GET_BSSID, &cur_bssid, sizeof(cur_bssid), false);
if (err != BCME_NOTASSOCIATED && memcmp(&ether_null, &cur_bssid, ETHER_ADDR_LEN)) {
// merge current connected bss
buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_ATOMIC);
if (!buf) {
ESCAN_ERROR(("buffer alloc failed.\n"));
err = BCME_NOMEM;
goto exit;
}
*(u32 *)buf = htod32(WL_EXTRA_BUF_MAX);
err = wldev_ioctl(dev, WLC_GET_BSS_INFO, buf, WL_EXTRA_BUF_MAX, false);
if (unlikely(err)) {
ESCAN_ERROR(("Could not get bss info %d\n", err));
goto exit;
}
bi = (struct wl_bss_info *)(buf + 4);
len_prep = 0;
err = wl_escan_merge_scan_results(dev, info, extra+len_ret, bi,
&len_prep, buflen_from_user-len_ret);
len_ret += len_prep;
if (err)
goto exit;
bi = NULL;
}
#if defined(BSSCACHE)
bss_list = &escan->g_bss_cache_ctrl.m_cache_head->results;
node = escan->g_bss_cache_ctrl.m_cache_head;
@ -1230,112 +1370,40 @@ wl_escan_get_scan(
#if defined(BSSCACHE)
bi = node->results.bss_info;
#endif
/* overflow check cover fields before wpa IEs */
if (event + ETHER_ADDR_LEN + bi->SSID_len + IW_EV_UINT_LEN + IW_EV_FREQ_LEN +
IW_EV_QUAL_LEN >= end) {
err = -E2BIG;
if (!memcmp(&bi->BSSID, &cur_bssid, ETHER_ADDR_LEN)) {
ESCAN_SCAN(("skip connected AP %pM\n", &cur_bssid));
#if defined(BSSCACHE)
node = node->next;
#endif
continue;
}
len_prep = 0;
err = wl_escan_merge_scan_results(dev, info, extra+len_ret, bi,
&len_prep, buflen_from_user-len_ret);
len_ret += len_prep;
if (err)
goto exit;
}
#if defined(RSSIAVG)
rssi = wl_get_avg_rssi(&escan->g_rssi_cache_ctrl, &bi->BSSID);
if (rssi == RSSI_MINVAL)
rssi = MIN(dtoh16(bi->RSSI), RSSI_MAXVAL);
#else
// terence 20150419: limit the max. rssi to -2 or the bss will be filtered out in android OS
rssi = MIN(dtoh16(bi->RSSI), RSSI_MAXVAL);
#endif
channel = wf_chspec_ctlchan(wl_chspec_driver_to_host(escan->ioctl_ver, bi->chanspec));
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;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN);
event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN);
/* SSID */
iwe.u.data.length = dtoh32(bi->SSID_len);
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID);
/* Mode */
if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) {
iwe.cmd = SIOCGIWMODE;
if (dtoh16(bi->capability) & DOT11_CAP_ESS)
iwe.u.mode = IW_MODE_INFRA;
else
iwe.u.mode = IW_MODE_ADHOC;
event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_UINT_LEN);
}
/* Channel */
iwe.cmd = SIOCGIWFREQ;
#if 1
iwe.u.freq.m = wf_channel2mhz(channel, channel <= CH_MAX_2G_CHANNEL ?
WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G);
#else
iwe.u.freq.m = wf_channel2mhz(bi->n_cap ?
bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec),
CHSPEC_CHANNEL(bi->chanspec) <= CH_MAX_2G_CHANNEL ?
WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G);
#endif
iwe.u.freq.e = 6;
event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN);
/* Channel quality */
iwe.cmd = IWEVQUAL;
iwe.u.qual.qual = rssi_to_qual(rssi);
iwe.u.qual.level = 0x100 + rssi;
iwe.u.qual.noise = 0x100 + bi->phy_noise;
event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN);
wl_iw_handle_scanresults_ies(&event, end, info, bi);
/* Encryption */
iwe.cmd = SIOCGIWENCODE;
if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY)
iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event);
/* Rates */
if (bi->rateset.count <= sizeof(bi->rateset.rates)) {
if (event + IW_MAX_BITRATES*IW_EV_PARAM_LEN >= end) {
err = -E2BIG;
goto exit;
}
value = event + IW_EV_LCP_LEN;
iwe.cmd = SIOCGIWRATE;
/* Those two flags are ignored... */
iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) {
iwe.u.bitrate.value = (bi->rateset.rates[j] & 0x7f) * 500000;
value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe,
IW_EV_PARAM_LEN);
}
event = value;
}
#if defined(BSSCACHE)
node = node->next;
#endif
}
dwrq->length = event - extra;
if ((len_ret + WE_ADD_EVENT_FIX) < dwrq->length)
dwrq->length = len_ret;
dwrq->flags = 0; /* todo */
ESCAN_SCAN(("scanned AP count (%d)\n", i));
exit:
kfree(buf);
dwrq->length = len_ret;
ESCAN_SCAN(("scanned AP count (%d)\n", i));
mutex_unlock(&escan->usr_sync);
return err;
}
s32 wl_escan_autochannel(struct net_device *dev, char* command, int total_len)
{
struct wl_escan_info *escan = g_escan;
struct dhd_pub *dhd = dhd_get_pub(dev);
struct wl_escan_info *escan = dhd->escan;
int ret = 0;
int bytes_written = -1;
@ -1432,7 +1500,7 @@ static s32 wl_escan_init(struct wl_escan_info *escan)
void wl_escan_detach(dhd_pub_t *dhdp)
{
struct wl_escan_info *escan = g_escan;
struct wl_escan_info *escan = dhdp->escan;
printf("%s: Enter\n", __FUNCTION__);
@ -1448,7 +1516,7 @@ void wl_escan_detach(dhd_pub_t *dhdp)
escan->escan_ioctl_buf = NULL;
}
DHD_OS_PREFREE(dhdp, escan, sizeof(struct wl_escan_info));
g_escan = NULL;
dhdp->escan = NULL;
}
int
@ -1463,7 +1531,7 @@ 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;
dhdp->escan = (void *)escan;
memset(escan, 0, sizeof(struct wl_escan_info));
/* we only care about main interface so save a global here */

View File

@ -27,6 +27,11 @@ struct escan_event_q {
s8 edata[1];
};
struct pmk_list {
pmkid_list_t pmkids;
pmkid_t foo[MAXPMKID - 1];
};
/* donlge escan state */
enum escan_state {
ESCAN_STATE_IDLE,
@ -66,6 +71,8 @@ typedef struct wl_escan_info {
#if defined(BSSCACHE)
wl_bss_cache_ctrl_t g_bss_cache_ctrl;
#endif
struct pmk_list pmk_list;
wl_conn_info_t conn_info;
} wl_escan_info_t;
void wl_escan_event(struct net_device *dev, const wl_event_msg_t * e, void *data);

View File

@ -48,6 +48,7 @@
#ifdef WL_ESCAN
#include <wl_escan.h>
#endif
#include <dhd_config.h>
typedef const struct si_pub si_t;
@ -105,10 +106,6 @@ uint iw_msg_level = WL_ERROR_LEVEL;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
#include <linux/rtnetlink.h>
#endif
#if defined(SOFTAP)
struct net_device *ap_net_dev = NULL;
tsk_ctl_t ap_eth_ctl; /* apsta AP netdev waiter thread */
#endif /* SOFTAP */
extern bool wl_iw_conn_status_str(uint32 event_type, uint32 status,
uint32 reason, char* stringBuf, uint buflen);
@ -133,6 +130,7 @@ extern int dhd_wait_pend8021x(struct net_device *dev);
#define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST)
#endif /* WIRELESS_EXT < 19 */
#ifndef WL_ESCAN
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
#define DAEMONIZE(a) do { \
@ -163,6 +161,11 @@ typedef struct iscan_buf {
char iscan_buf[WLC_IW_ISCAN_MAXLEN];
} iscan_buf_t;
struct pmk_list {
pmkid_list_t pmkids;
pmkid_t foo[MAXPMKID - 1];
};
typedef struct iscan_info {
struct net_device *dev;
struct timer_list timer;
@ -179,11 +182,10 @@ typedef struct iscan_info {
long sysioc_pid;
struct semaphore sysioc_sem;
struct completion sysioc_exited;
char ioctlbuf[WLC_IOCTL_SMLEN];
struct pmk_list pmk_list;
wl_conn_info_t conn_info;
} iscan_info_t;
iscan_info_t *g_iscan = NULL;
static void wl_iw_timerfunc(ulong data);
static void wl_iw_set_event_mask(struct net_device *dev);
static int wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action);
@ -471,6 +473,42 @@ wl_iw_set_pm(
}
#endif /* WIRELESS_EXT > 12 */
static void
wl_iw_check_handshake(struct net_device *dev, bool set)
{
#ifndef WL_CFG80211
struct dhd_pub *dhd = dhd_get_pub(dev);
int cur_eapol_status = 0;
int wpa_auth = 0;
int error = -EINVAL;
if (dhd && dhd->conf)
cur_eapol_status = dhd->conf->eapol_status;
if (set) {
if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &wpa_auth))) {
WL_ERROR(("%s: wpa_auth get error %d\n", __FUNCTION__, error));
return;
}
if (wpa_auth & (WPA_AUTH_PSK|WPA2_AUTH_PSK))
dhd->conf->eapol_status = EAPOL_STATUS_WPA_START;
else
dhd->conf->eapol_status = EAPOL_STATUS_NONE;
} else {
if (cur_eapol_status >= EAPOL_STATUS_WPA_START &&
cur_eapol_status < EAPOL_STATUS_WPA_END) {
WL_ERROR(("%s: WPA failed at %d\n", __FUNCTION__, cur_eapol_status));
dhd->conf->eapol_status = EAPOL_STATUS_NONE;
} else if (cur_eapol_status >= EAPOL_STATUS_WPS_WSC_START &&
cur_eapol_status < EAPOL_STATUS_WPS_DONE) {
WL_ERROR(("%s: WPS failed at %d\n", __FUNCTION__, cur_eapol_status));
dhd->conf->eapol_status = EAPOL_STATUS_NONE;
}
}
#endif
return;
}
int
wl_iw_send_priv_event(
struct net_device *dev,
@ -583,6 +621,21 @@ wl_iw_set_freq(
{
int error, chan;
uint sf = 0;
struct dhd_pub *dhd = dhd_get_pub(dev);
wl_conn_info_t *conn_info = NULL;
#ifdef WL_ESCAN
wl_escan_info_t *escan;
if (dhd && dhd->escan) {
escan = (wl_escan_info_t *)dhd->escan;
conn_info = &escan->conn_info;
}
#else
iscan_info_t *iscan;
if (dhd && dhd->iscan) {
iscan = (iscan_info_t *)dhd->iscan;
conn_info = &iscan->conn_info;
}
#endif
WL_TRACE(("%s: SIOCSIWFREQ\n", dev->name));
@ -608,6 +661,8 @@ wl_iw_set_freq(
}
chan = wf_mhz2channel(fwrq->m, sf);
}
if (conn_info)
conn_info->channel = chan;
WL_ERROR(("%s: chan=%d\n", __FUNCTION__, chan));
chan = htod32(chan);
if ((error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan)))) {
@ -652,8 +707,25 @@ wl_iw_set_mode(
)
{
int infra = 0, ap = 0, error = 0;
struct dhd_pub *dhd = dhd_get_pub(dev);
wl_conn_info_t *conn_info = NULL;
#ifdef WL_ESCAN
wl_escan_info_t *escan;
if (dhd && dhd->escan) {
escan = (wl_escan_info_t *)dhd->escan;
conn_info = &escan->conn_info;
}
#else
iscan_info_t *iscan;
if (dhd && dhd->iscan) {
iscan = (iscan_info_t *)dhd->iscan;
conn_info = &iscan->conn_info;
}
#endif
WL_TRACE(("%s: SIOCSIWMODE\n", dev->name));
if (conn_info)
memset(conn_info, 0, sizeof(wl_conn_info_t));
switch (*uwrq) {
case IW_MODE_MASTER:
@ -997,6 +1069,21 @@ wl_iw_set_wap(
)
{
int error = -EINVAL;
struct dhd_pub *dhd = dhd_get_pub(dev);
wl_conn_info_t *conn_info = NULL;
#ifdef WL_ESCAN
wl_escan_info_t *escan;
if (dhd && dhd->escan) {
escan = (wl_escan_info_t *)dhd->escan;
conn_info = &escan->conn_info;
}
#else
iscan_info_t *iscan;
if (dhd && dhd->iscan) {
iscan = (iscan_info_t *)dhd->iscan;
conn_info = &iscan->conn_info;
}
#endif
WL_TRACE(("%s: SIOCSIWAP\n", dev->name));
@ -1013,17 +1100,26 @@ wl_iw_set_wap(
if ((error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)))) {
WL_ERROR(("%s: WLC_DISASSOC failed (%d).\n", __FUNCTION__, error));
}
wl_iw_check_handshake(dev, FALSE);
return 0;
}
/* WL_ASSOC(("Assoc to %s\n", bcm_ether_ntoa((struct ether_addr *)&(awrq->sa_data),
* eabuf)));
*/
/* Reassociate to the specified AP */
if ((error = dev_wlc_ioctl(dev, WLC_REASSOC, awrq->sa_data, ETHER_ADDR_LEN))) {
WL_ERROR(("%s: WLC_REASSOC failed (%d).\n", __FUNCTION__, error));
return error;
if (conn_info)
memcpy(&conn_info->bssid, awrq->sa_data, ETHER_ADDR_LEN);
if (conn_info && conn_info->ssid.SSID_len) {
if ((error = wl_ext_connect(dev, conn_info)))
return error;
} else {
if ((error = dev_wlc_ioctl(dev, WLC_REASSOC, awrq->sa_data, ETHER_ADDR_LEN))) {
WL_ERROR(("%s: WLC_REASSOC failed (%d).\n", __FUNCTION__, error));
return error;
}
WL_ERROR(("%s: join BSSID="MACSTR"\n", __FUNCTION__, MAC2STR((u8 *)awrq->sa_data)));
}
WL_ERROR(("%s: join BSSID="MACSTR"\n", __FUNCTION__, MAC2STR((u8 *)awrq->sa_data)));
wl_iw_check_handshake(dev, TRUE);
return 0;
}
@ -1084,6 +1180,7 @@ wl_iw_mlme(
WL_ERROR(("%s: Invalid ioctl data.\n", __FUNCTION__));
return error;
}
wl_iw_check_handshake(dev, FALSE);
return error;
}
@ -1176,13 +1273,16 @@ wl_iw_iscan_get_aplist(
{
wl_scan_results_t *list;
iscan_buf_t * buf;
iscan_info_t *iscan = g_iscan;
iscan_info_t *iscan;
struct sockaddr *addr = (struct sockaddr *) extra;
struct iw_quality qual[IW_MAX_AP];
wl_bss_info_t *bi = NULL;
int i;
int16 rssi;
struct dhd_pub *dhd = dhd_get_pub(dev);
if (dhd && dhd->iscan)
iscan = (iscan_info_t *)dhd->iscan;
WL_TRACE(("%s: SIOCGIWAPLIST\n", dev->name));
@ -1282,7 +1382,10 @@ wl_iw_iscan_set_scan(
)
{
wlc_ssid_t ssid;
iscan_info_t *iscan = g_iscan;
struct dhd_pub *dhd = dhd_get_pub(dev);
iscan_info_t *iscan;
if (dhd && dhd->iscan)
iscan = (iscan_info_t *)dhd->iscan;
WL_TRACE(("%s: SIOCSIWSCAN iscan=%p\n", dev->name, iscan));
@ -1586,10 +1689,13 @@ wl_iw_iscan_get_scan(
int ii, j;
int apcnt;
char *event = extra, *end = extra + dwrq->length, *value;
iscan_info_t *iscan = g_iscan;
iscan_buf_t * p_buf;
int16 rssi;
int channel;
struct dhd_pub *dhd = dhd_get_pub(dev);
iscan_info_t *iscan;
if (dhd && dhd->iscan)
iscan = (iscan_info_t *)dhd->iscan;
WL_TRACE(("%s: %s SIOCGIWSCAN\n", __FUNCTION__, dev->name));
@ -1722,6 +1828,21 @@ wl_iw_set_essid(
{
wlc_ssid_t ssid;
int error;
struct dhd_pub *dhd = dhd_get_pub(dev);
wl_conn_info_t *conn_info = NULL;
#ifdef WL_ESCAN
wl_escan_info_t *escan;
if (dhd && dhd->escan) {
escan = (wl_escan_info_t *)dhd->escan;
conn_info = &escan->conn_info;
}
#else
iscan_info_t *iscan;
if (dhd && dhd->iscan) {
iscan = (iscan_info_t *)dhd->iscan;
conn_info = &iscan->conn_info;
}
#endif
WL_TRACE(("%s: SIOCSIWESSID\n", dev->name));
@ -1736,11 +1857,21 @@ wl_iw_set_essid(
memcpy(ssid.SSID, extra, ssid.SSID_len);
ssid.SSID_len = htod32(ssid.SSID_len);
if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid)))) {
WL_ERROR(("%s: WLC_SET_SSID failed (%d).\n", __FUNCTION__, error));
return error;
if (conn_info) {
memcpy(conn_info->ssid.SSID, ssid.SSID, ssid.SSID_len);
conn_info->ssid.SSID_len = ssid.SSID_len;
}
WL_ERROR(("%s: join SSID=%s\n", __FUNCTION__, ssid.SSID));
if (conn_info && memcmp(&ether_null, &conn_info->bssid, ETHER_ADDR_LEN)) {
if ((error = wl_ext_connect(dev, conn_info)))
return error;
} else {
if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid)))) {
WL_ERROR(("%s: WLC_SET_SSID failed (%d).\n", __FUNCTION__, error));
return error;
}
WL_ERROR(("%s: join SSID=%s\n", __FUNCTION__, ssid.SSID));
}
wl_iw_check_handshake(dev, TRUE);
}
/* If essid null then it is "iwconfig <interface> essid off" command */
else {
@ -1751,6 +1882,7 @@ wl_iw_set_essid(
WL_ERROR(("%s: WLC_DISASSOC failed (%d).\n", __FUNCTION__, error));
return error;
}
wl_iw_check_handshake(dev, FALSE);
}
return 0;
}
@ -2410,6 +2542,7 @@ wl_iw_set_encodeext(
wl_wsec_key_t key;
int error;
struct iw_encode_ext *iwe;
struct dhd_pub *dhd = dhd_get_pub(dev);
WL_TRACE(("%s: SIOCSIWENCODEEXT\n", dev->name));
@ -2535,15 +2668,13 @@ wl_iw_set_encodeext(
error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
if (error)
return error;
if (dhd && dhd->conf)
dhd->conf->eapol_status = EAPOL_STATUS_WPA_END;
}
return 0;
}
struct {
pmkid_list_t pmkids;
pmkid_t foo[MAXPMKID-1];
} pmkid_list;
/* wpa2 pmk list */
static int
wl_iw_set_pmksa(
struct net_device *dev,
@ -2552,17 +2683,34 @@ wl_iw_set_pmksa(
char *extra
)
{
struct pmk_list *pmk_list = NULL;
struct iw_pmksa *iwpmksa;
uint i;
char eabuf[ETHER_ADDR_STR_LEN];
pmkid_t * pmkid_array = pmkid_list.pmkids.pmkid;
pmkid_t *pmkid_array = NULL;
struct dhd_pub *dhd = dhd_get_pub(dev);
#ifdef WL_ESCAN
wl_escan_info_t *escan;
if (dhd && dhd->escan) {
escan = (wl_escan_info_t *)dhd->escan;
pmk_list = &escan->pmk_list;
}
#else
iscan_info_t *iscan;
if (dhd && dhd->iscan) {
iscan = (iscan_info_t *)dhd->iscan;
pmk_list = &iscan->pmk_list;
}
#endif
WL_TRACE(("%s: SIOCSIWPMKSA\n", dev->name));
if (pmk_list)
pmkid_array = pmk_list->pmkids.pmkid;
iwpmksa = (struct iw_pmksa *)extra;
bzero((char *)eabuf, ETHER_ADDR_STR_LEN);
if (iwpmksa->cmd == IW_PMKSA_FLUSH) {
WL_TRACE(("wl_iw_set_pmksa - IW_PMKSA_FLUSH\n"));
bzero((char *)&pmkid_list, sizeof(pmkid_list));
bzero((char *)pmk_list, sizeof(struct pmk_list));
}
if (iwpmksa->cmd == IW_PMKSA_REMOVE) {
pmkid_list_t pmkid, *pmkidptr;
@ -2578,11 +2726,11 @@ wl_iw_set_pmksa(
WL_TRACE(("%02x ", pmkidptr->pmkid[0].PMKID[j]));
WL_TRACE(("\n"));
}
for (i = 0; i < pmkid_list.pmkids.npmkid; i++)
for (i = 0; i < pmk_list->pmkids.npmkid; i++)
if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_array[i].BSSID,
ETHER_ADDR_LEN))
break;
for (; i < pmkid_list.pmkids.npmkid; i++) {
for (; i < pmk_list->pmkids.npmkid; i++) {
bcopy(&pmkid_array[i+1].BSSID,
&pmkid_array[i].BSSID,
ETHER_ADDR_LEN);
@ -2590,18 +2738,18 @@ wl_iw_set_pmksa(
&pmkid_array[i].PMKID,
WPA2_PMKID_LEN);
}
pmkid_list.pmkids.npmkid--;
pmk_list->pmkids.npmkid--;
}
if (iwpmksa->cmd == IW_PMKSA_ADD) {
bcopy(&iwpmksa->bssid.sa_data[0],
&pmkid_array[pmkid_list.pmkids.npmkid].BSSID,
&pmkid_array[pmk_list->pmkids.npmkid].BSSID,
ETHER_ADDR_LEN);
bcopy(&iwpmksa->pmkid[0], &pmkid_array[pmkid_list.pmkids.npmkid].PMKID,
bcopy(&iwpmksa->pmkid[0], &pmkid_array[pmk_list->pmkids.npmkid].PMKID,
WPA2_PMKID_LEN);
{
uint j;
uint k;
k = pmkid_list.pmkids.npmkid;
k = pmk_list->pmkids.npmkid;
BCM_REFERENCE(k);
WL_TRACE(("wl_iw_set_pmksa,IW_PMKSA_ADD - PMKID: %s = ",
bcm_ether_ntoa(&pmkid_array[k].BSSID,
@ -2610,10 +2758,10 @@ wl_iw_set_pmksa(
WL_TRACE(("%02x ", pmkid_array[k].PMKID[j]));
WL_TRACE(("\n"));
}
pmkid_list.pmkids.npmkid++;
pmk_list->pmkids.npmkid++;
}
WL_TRACE(("PRINTING pmkid LIST - No of elements %d\n", pmkid_list.pmkids.npmkid));
for (i = 0; i < pmkid_list.pmkids.npmkid; i++) {
WL_TRACE(("PRINTING pmkid LIST - No of elements %d\n", pmk_list->pmkids.npmkid));
for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
uint j;
WL_TRACE(("PMKID[%d]: %s = ", i,
bcm_ether_ntoa(&pmkid_array[i].BSSID,
@ -2623,7 +2771,7 @@ wl_iw_set_pmksa(
printf("\n");
}
WL_TRACE(("\n"));
dev_wlc_bufvar_set(dev, "pmkid_info", (char *)&pmkid_list, sizeof(pmkid_list));
dev_wlc_bufvar_set(dev, "pmkid_info", (char *)pmk_list, sizeof(struct pmk_list));
return 0;
}
@ -3101,6 +3249,12 @@ wl_iw_ioctl(
char *extra = NULL;
size_t token_size = 1;
int max_tokens = 0, ret = 0;
#ifndef WL_ESCAN
struct dhd_pub *dhd = dhd_get_pub(dev);
iscan_info_t *iscan;
if (dhd && dhd->iscan)
iscan = (iscan_info_t *)dhd->iscan;
#endif
if (cmd < SIOCIWFIRST ||
IW_IOCTL_IDX(cmd) >= ARRAYSIZE(wl_iw_handler) ||
@ -3137,7 +3291,7 @@ wl_iw_ioctl(
#if WIRELESS_EXT > 13
case SIOCGIWSCAN:
#ifndef WL_ESCAN
if (g_iscan)
if (iscan)
max_tokens = wrq->u.data.length;
else
#endif
@ -3306,6 +3460,12 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
uint32 datalen = ntoh32(e->datalen);
uint32 status = ntoh32(e->status);
uint32 reason = ntoh32(e->reason);
#ifndef WL_ESCAN
struct dhd_pub *dhd = dhd_get_pub(dev);
iscan_info_t *iscan;
if (dhd && dhd->iscan)
iscan = (iscan_info_t *)dhd->iscan;
#endif
memset(&wrqu, 0, sizeof(wrqu));
memset(extra, 0, sizeof(extra));
@ -3329,16 +3489,17 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
wrqu.data.length = strlen(extra);
bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN);
bzero(&extra, ETHER_ADDR_LEN);
wl_iw_check_handshake(dev, FALSE);
break;
case WLC_E_LINK:
cmd = SIOCGIWAP;
wrqu.data.length = strlen(extra);
if (!(flags & WLC_EVENT_MSG_LINK)) {
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);
wl_iw_check_handshake(dev, FALSE);
} else {
printf("%s: Link UP with "MACSTR"\n", __FUNCTION__,
MAC2STR((u8 *)wrqu.addr.sa_data));
@ -3435,9 +3596,9 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
WL_TRACE(("event WLC_E_SCAN_COMPLETE\n"));
// terence 20150224: fix "wlan0: (WE) : Wireless Event too big (65306)"
memset(&wrqu, 0, sizeof(wrqu));
if ((g_iscan) && (g_iscan->sysioc_pid >= 0) &&
(g_iscan->iscan_state != ISCAN_STATE_IDLE))
up(&g_iscan->sysioc_sem);
if ((iscan) && (iscan->sysioc_pid >= 0) &&
(iscan->iscan_state != ISCAN_STATE_IDLE))
up(&iscan->sysioc_sem);
break;
#endif
@ -3449,7 +3610,7 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
if (cmd) {
#ifndef WL_ESCAN
if (cmd == SIOCGIWSCAN) {
if ((!g_iscan) || (g_iscan->sysioc_pid < 0)) {
if ((!iscan) || (iscan->sysioc_pid < 0)) {
wireless_send_event(dev, cmd, &wrqu, NULL);
};
} else
@ -3875,12 +4036,10 @@ _iscan_sysioc_thread(void *data)
printf("%s: was terminated\n", __FUNCTION__);
complete_and_exit(&iscan->sysioc_exited, 0);
}
#endif /* WL_ESCAN */
int
wl_iw_attach(struct net_device *dev, void * dhdp)
wl_iw_attach(struct net_device *dev, dhd_pub_t *dhdp)
{
#ifndef WL_ESCAN
iscan_info_t *iscan = NULL;
printf("%s: Enter\n", __FUNCTION__);
@ -3891,13 +4050,13 @@ wl_iw_attach(struct net_device *dev, void * dhdp)
iscan = kmalloc(sizeof(iscan_info_t), GFP_KERNEL);
if (!iscan)
return -ENOMEM;
dhdp->iscan = (void *)iscan;
memset(iscan, 0, sizeof(iscan_info_t));
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
iscan->kthread = NULL;
#endif
iscan->sysioc_pid = -1;
/* we only care about main interface so save a global here */
g_iscan = iscan;
iscan->dev = dev;
iscan->iscan_state = ISCAN_STATE_IDLE;
@ -3921,15 +4080,13 @@ wl_iw_attach(struct net_device *dev, void * dhdp)
#endif
if (iscan->sysioc_pid < 0)
return -ENOMEM;
#endif /* WL_ESCAN */
return 0;
}
void wl_iw_detach(void)
void wl_iw_detach(dhd_pub_t *dhdp)
{
#ifndef WL_ESCAN
iscan_buf_t *buf;
iscan_info_t *iscan = g_iscan;
iscan_info_t *iscan = dhdp->iscan;
if (!iscan)
return;
if (iscan->sysioc_pid >= 0) {
@ -3943,8 +4100,8 @@ void wl_iw_detach(void)
iscan->list_hdr = buf;
}
kfree(iscan);
g_iscan = NULL;
#endif
dhdp->iscan = NULL;
}
#endif /* !WL_ESCAN */
#endif /* USE_IW */

View File

@ -35,6 +35,8 @@
#include <typedefs.h>
#include <ethernet.h>
#include <wlioctl.h>
#include <dngl_stats.h>
#include <dhd.h>
#define WL_SCAN_PARAMS_SSID_MAX 10
#define GET_SSID "SSID="
@ -123,15 +125,15 @@ extern const struct iw_handler_def wl_iw_handler_def;
extern int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
extern void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data);
extern int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats);
int wl_iw_attach(struct net_device *dev, void * dhdp);
int wl_iw_send_priv_event(struct net_device *dev, char *flag);
#ifdef WL_ESCAN
int wl_iw_handle_scanresults_ies(char **event_p, char *end,
struct iw_request_info *info, wl_bss_info_t *bi);
#else
int wl_iw_attach(struct net_device *dev, dhd_pub_t *dhdp);
void wl_iw_detach(dhd_pub_t *dhdp);
#endif
void wl_iw_detach(void);
#define CSCAN_COMMAND "CSCAN "
#define CSCAN_TLV_PREFIX 'S'
#define CSCAN_TLV_VERSION 1

View File

@ -499,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_map_country_list(dhd_get_pub(dev), &cspec, 0);
error = dhd_conf_map_country_list(dhd_get_pub(dev), &cspec);
if (error)
dhd_get_customized_country_code(dev, (char *)&cspec.country_abbrev, &cspec);