aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorcodeworkx <daniel.hillenbrand@codeworkx.de>2012-08-03 23:12:09 +0200
committercodeworkx <daniel.hillenbrand@codeworkx.de>2012-08-03 23:12:09 +0200
commit52215890ef7c4d06fd3323f8315d85f14d637a91 (patch)
tree2f97aaab909de9fa903ba52224f6f643e2f25cf5 /drivers
parent4309a7ffa8aa46ac2fc4090cebc3efeb00dce72f (diff)
downloadkernel_samsung_smdk4412-52215890ef7c4d06fd3323f8315d85f14d637a91.zip
kernel_samsung_smdk4412-52215890ef7c4d06fd3323f8315d85f14d637a91.tar.gz
kernel_samsung_smdk4412-52215890ef7c4d06fd3323f8315d85f14d637a91.tar.bz2
samsung opensource update4
Change-Id: I9db25f213bb1577c4468873c66b230a0566b6cf2
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/s5c73m3.c6
-rw-r--r--drivers/media/video/s5c73m3.h4
-rw-r--r--drivers/mmc/core/core.c4
-rw-r--r--drivers/mmc/host/sdhci.c11
-rw-r--r--drivers/net/wireless/bcmdhd/Makefile24
-rw-r--r--drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_linux.c8
-rw-r--r--drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc.c17
-rw-r--r--drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc_linux.c6
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd.h3
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cdc.c434
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cfg80211.c1
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_common.c7
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_custom_sec.c12
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_linux.c45
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sdio.c113
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sec_feature.h12
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_wlfc.h19
-rw-r--r--drivers/net/wireless/bcmdhd/src/include/epivers.h10
-rw-r--r--drivers/net/wireless/bcmdhd/src/include/sbchipc.h6
-rw-r--r--drivers/net/wireless/bcmdhd/src/include/wlioctl.h6
-rw-r--r--drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c48
-rw-r--r--drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.c263
-rw-r--r--drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.h1
-rw-r--r--drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.c15
-rw-r--r--drivers/net/wireless/bcmdhd/src/wl/sys/wl_iw.c21
-rw-r--r--drivers/net/wireless/bcmdhd/src/wl/sys/wl_iw.h1
-rw-r--r--drivers/net/wireless/bcmdhd/src/wl/sys/wldev_common.c9
-rw-r--r--drivers/video/samsung/s5p-dsim.c22
28 files changed, 801 insertions, 327 deletions
diff --git a/drivers/media/video/s5c73m3.c b/drivers/media/video/s5c73m3.c
index 5db5f7f..47c4297 100644
--- a/drivers/media/video/s5c73m3.c
+++ b/drivers/media/video/s5c73m3.c
@@ -70,9 +70,8 @@ static const struct s5c73m3_frmsizeenum preview_frmsizes[] = {
{ S5C73M3_PREVIEW_QVGA, 320, 240, 0x01 },
{ S5C73M3_PREVIEW_CIF, 352, 288, 0x0E },
{ S5C73M3_PREVIEW_VGA, 640, 480, 0x02 },
- { S5C73M3_PREVIEW_704X576, 704, 576, 0x09 },
+ { S5C73M3_PREVIEW_800X600, 800, 600, 0x09 },
{ S5C73M3_PREVIEW_880X720, 880, 720, 0x03 },
- { S5C73M3_PREVIEW_960X640, 960, 640, 0x0B },
{ S5C73M3_PREVIEW_960X720, 960, 720, 0x04 },
{ S5C73M3_PREVIEW_1008X672, 1008, 672, 0x0F },
{ S5C73M3_PREVIEW_1184X666, 1184, 666, 0x05 },
@@ -80,10 +79,13 @@ static const struct s5c73m3_frmsizeenum preview_frmsizes[] = {
{ S5C73M3_VDIS_720P, 1536, 864, 0x07 },
{ S5C73M3_PREVIEW_1080P, 1920, 1080, 0x0A},
{ S5C73M3_VDIS_1080P, 2304, 1296, 0x0C},
+ { S5C73M3_PREVIEW_D1, 720, 480, 0x0B },
};
static const struct s5c73m3_frmsizeenum capture_frmsizes[] = {
{ S5C73M3_CAPTURE_VGA, 640, 480, 0x10 },
+ { S5C73M3_CAPTURE_960x540, 960, 540, 0x20 },
+ { S5C73M3_CAPTURE_960x720, 960, 720, 0x30 },
{ S5C73M3_CAPTURE_1024X768, 1024, 768, 0xD0 },
{ S5C73M3_CAPTURE_HD, 1280, 720, 0x40 },
{ S5C73M3_CAPTURE_2MP, 1600, 1200, 0x70 },
diff --git a/drivers/media/video/s5c73m3.h b/drivers/media/video/s5c73m3.h
index 40d7eaf..aaf4007 100644
--- a/drivers/media/video/s5c73m3.h
+++ b/drivers/media/video/s5c73m3.h
@@ -71,7 +71,7 @@ enum s5c73m3_prev_frmsize {
S5C73M3_PREVIEW_VGA,
S5C73M3_PREVIEW_D1,
S5C73M3_PREVIEW_WVGA,
- S5C73M3_PREVIEW_704X576,
+ S5C73M3_PREVIEW_800X600,
S5C73M3_PREVIEW_880X720,
S5C73M3_PREVIEW_960X640,
S5C73M3_PREVIEW_960X720,
@@ -88,6 +88,8 @@ enum s5c73m3_prev_frmsize {
enum s5c73m3_cap_frmsize {
S5C73M3_CAPTURE_VGA, /* 640 x 480 */
S5C73M3_CAPTURE_WVGA, /* 800 x 480 */
+ S5C73M3_CAPTURE_960x540, /* 960 x 540 */
+ S5C73M3_CAPTURE_960x720, /* 960 x 720 */
S5C73M3_CAPTURE_1024X768, /* 1024 x 768 */
S5C73M3_CAPTURE_HD, /* 1280 x 720 */
S5C73M3_CAPTURE_W1MP, /* 1600 x 960 */
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 0b2b5b4..e33a805 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -268,8 +268,8 @@ static void mmc_wait_for_req_done(struct mmc_host *host,
wait_for_completion(&mrq->completion);
cmd = mrq->cmd;
- if (!cmd->error || !cmd->retries ||
- mmc_card_removed(host->card))
+
+ if (mmc_card_removed(host->card))
return;
/* if card is mmc type and nonremovable, and there are erros after
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 9f23876..b876dcc 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -643,9 +643,14 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd)
/* timeout in us */
if (!data)
target_timeout = cmd->cmd_timeout_ms * 1000;
- else
- target_timeout = data->timeout_ns / 1000 +
- data->timeout_clks / host->clock;
+ else {
+ /* patch added for divide by zero once issue. */
+ if (host && host->clock)
+ target_timeout = data->timeout_ns / 1000 +
+ data->timeout_clks / host->clock;
+ else
+ return 0;
+ }
if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
host->timeout_clk = host->clock / 1000;
diff --git a/drivers/net/wireless/bcmdhd/Makefile b/drivers/net/wireless/bcmdhd/Makefile
index 1a27ef0..48e5226 100644
--- a/drivers/net/wireless/bcmdhd/Makefile
+++ b/drivers/net/wireless/bcmdhd/Makefile
@@ -17,6 +17,8 @@ DHDCFLAGS += -DPROP_TXSTATUS
DHDCFLAGS += -DVSDB -DHT40_GO
DHDCFLAGS += -DWL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
DHDCFLAGS += -DDHD_USE_IDLECOUNT
+DHDCFLAGS += -DSUPPORT_AMPDU_MPDU_CMD
+DHDCFLAGS += -DVSDB_DYNAMIC_F2_BLKSIZE -DSDIO_F2_BLKSIZE=512 -DVSDB_F2_BLKSIZE=64
endif
ifeq ($(CONFIG_BCM4334),y)
DHDCFLAGS += -DBCM4334_CHIP -DHW_OOB -DBCM4334_CHECK_CHIP_REV
@@ -25,26 +27,32 @@ DHDCFLAGS += -DPROP_TXSTATUS
DHDCFLAGS += -DVSDB -DHT40_GO
DHDCFLAGS += -DWL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
DHDCFLAGS += -DDHD_USE_IDLECOUNT
+DHDCFLAGS += -DSUPPORT_AMPDU_MPDU_CMD
+DHDCFLAGS += -DVSDB_DYNAMIC_F2_BLKSIZE -DSDIO_F2_BLKSIZE=512 -DVSDB_F2_BLKSIZE=64
endif
ifeq ($(CONFIG_BCM4330),m)
DHDCFLAGS += -DBCM4330_CHIP
DHDCFLAGS += -DMCAST_LIST_ACCUMULATION
DHDCFLAGS += -DCONFIG_CONTROL_PM
+DHDCFLAGS += -DROAM_ENABLE -DROAM_API -DROAM_CHANNEL_CACHE
endif
ifeq ($(CONFIG_BCM4330),y)
DHDCFLAGS += -DBCM4330_CHIP
DHDCFLAGS += -DMCAST_LIST_ACCUMULATION
DHDCFLAGS += -DCONFIG_CONTROL_PM
+DHDCFLAGS += -DROAM_ENABLE -DROAM_API -DROAM_CHANNEL_CACHE
endif
ifeq ($(CONFIG_BCM43241),m)
DHDCFLAGS += -DBCM43241_CHIP -DHW_OOB
DHDCFLAGS += -DMCAST_LIST_ACCUMULATION
+DHDCFLAGS += -DMIMO_ANT_SETTING -DCONFIG_CONTROL_PM
DHDCFLAGS += -fno-pic
endif
ifeq ($(CONFIG_BCM43241),y)
DHDCFLAGS += -DBCM43241_CHIP -DHW_OOB
DHDCFLAGS += -DMCAST_LIST_ACCUMULATION
+DHDCFLAGS += -DMIMO_ANT_SETTING -DCONFIG_CONTROL_PM
endif
# For p2p connection issue
@@ -70,6 +78,10 @@ ifeq ($(CONFIG_MACH_SAMSUNG_T1),y)
DHDCFLAGS += -DUSE_CID_CHECK -DWRITE_MACADDR
endif
+ifeq ($(CONFIG_MACH_U1_NA_SPR),y)
+DHDCFLAGS += -DRDWR_MACADDR
+endif
+
DHDCFLAGS += -DROAM_ENABLE -DROAM_CHANNEL_CACHE -DROAM_API
# For Static Buffer
@@ -78,7 +90,7 @@ DHDCFLAGS += -DCONFIG_DHD_USE_STATIC_BUF
endif
# For CCX
-ifneq ($(CONFIG_TARGET_LOCALE_KOR),y)
+ifeq ($(CONFIG_BRCM_CCX),y)
DHDCFLAGS += -DBCMCCX
endif
@@ -100,7 +112,7 @@ endif
##############################################################
# dhd_sec_feature.h
-REGION_CODE := $(CONFIG_WLAN_REGION_CODE)
+REGION_CODE := 100
ifeq ($(CONFIG_TARGET_LOCALE_KOR),y)
REGION_CODE=200
@@ -120,6 +132,10 @@ REGION_CODE=101
endif
endif
+ifdef CONFIG_WLAN_REGION_CODE
+REGION_CODE=$(CONFIG_WLAN_REGION_CODE)
+endif
+
DHDCFLAGS += -DWLAN_REGION_CODE=$(REGION_CODE)
##############################################################
@@ -137,7 +153,11 @@ EXTRA_CFLAGS += -I$(src)/src/shared/
EXTRA_CFLAGS += -I$(src)/src/wl/bcmwifi/src/
EXTRA_CFLAGS += -I$(src)/src/wl/bcmwifi/include/
+ifeq ($(CONFIG_MACH_T0), y)
+#EXTRA_LDFLAGS += --strip-debug
+else
EXTRA_LDFLAGS += --strip-debug
+endif
KBUILD_CFLAGS += -I$(LINUXDIR)/include -I$(shell pwd)
obj-m += dhd.o
diff --git a/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_linux.c b/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_linux.c
index f7676d8..400397e 100644
--- a/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_linux.c
+++ b/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_linux.c
@@ -51,7 +51,7 @@ extern void dhdsdio_isr(void * args);
#if defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP)
/*SLP_wakelock_alternative_code*/
-struct device *pm_dev;
+struct device *pm_dev;
#endif /* CONFIG_PM_SLEEP && CUSTOMER_HW_SLP */
/**
* SDIO Host Controller info
@@ -188,6 +188,10 @@ int bcmsdh_probe(struct device *dev)
/* Get customer specific OOB IRQ parametres: IRQ number as IRQ type */
irq = dhd_customer_oob_irq_map(&irq_flags);
+#if defined(BCMHOST)
+ /* Do not disable this IRQ during suspend */
+ irq_flags |= IRQF_NO_SUSPEND;
+#endif
if (irq < 0) {
SDLX_MSG(("%s: Host irq is not defined\n", __FUNCTION__));
return 1;
@@ -237,7 +241,7 @@ int bcmsdh_probe(struct device *dev)
#if defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP)
/*SLP_wakelock_alternative_code*/
- pm_dev=sdhc->dev;
+ pm_dev=sdhc->dev;
ret = device_init_wakeup(pm_dev, 1);
printf("%s : device_init_wakeup(pm_dev) enable, ret = %d\n", __func__, ret);
#endif /* CONFIG_PM_SLEEP && CUSTOMER_HW_SLP */
diff --git a/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc.c b/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc.c
index 7d5bcac..d6a110a 100644
--- a/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc.c
@@ -522,6 +522,19 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name,
/* Now set it */
si->client_block_size[func] = blksize;
+#ifdef VSDB_DYNAMIC_F2_BLKSIZE
+ if (gInstance == NULL || gInstance->func[func] == NULL) {
+ sd_err(("%s: SDIO Device not present\n", __FUNCTION__));
+ bcmerror = BCME_NORESOURCE;
+ break;
+ }
+ sdio_claim_host(gInstance->func[func]);
+ bcmerror = sdio_set_block_size(gInstance->func[func], blksize);
+ if (bcmerror) {
+ sd_err(("%s: Failed to set F%d blocksize to %d\n", __FUNCTION__, func, blksize));
+ }
+ sdio_release_host(gInstance->func[func]);
+#endif
break;
}
@@ -1044,6 +1057,10 @@ sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
else if(pkt_len % DHD_SDALIGN) // write
pkt_len += DHD_SDALIGN - (pkt_len % DHD_SDALIGN);
+#ifdef VSDB_DYNAMIC_F2_BLKSIZE
+ if (write && pkt_len > 64 && (pkt_len % 64) == 32)
+ pkt_len += 32;
+#endif
#ifdef CONFIG_MMC_MSM7X00A
if ((pkt_len % 64) == 32) {
sd_trace(("%s: Rounding up TX packet +=32\n", __FUNCTION__));
diff --git a/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc_linux.c
index 83c1192..ca8478b 100644
--- a/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc_linux.c
+++ b/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc_linux.c
@@ -202,7 +202,7 @@ static int bcmsdh_sdmmc_suspend(struct device *pdev)
dhd_mmc_suspend = TRUE;
#if defined (CUSTOMER_HW_SAMSUNG) && defined (CONFIG_ARCH_TEGRA)
irq_set_irq_wake(390, 1);
-#endif
+#endif
smp_mb();
return 0;
@@ -225,7 +225,7 @@ static int bcmsdh_sdmmc_resume(struct device *pdev)
#if defined (CUSTOMER_HW_SAMSUNG) && defined (CONFIG_ARCH_TEGRA)
if (func->num == 2)
irq_set_irq_wake(390, 0);
-#endif
+#endif
smp_mb();
return 0;
@@ -276,11 +276,13 @@ static struct sdio_driver bcmsdh_sdmmc_driver = {
.remove = bcmsdh_sdmmc_remove,
.name = "bcmsdh_sdmmc",
.id_table = bcmsdh_sdmmc_ids,
+#if !defined(BCMHOST)
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM)
.drv = {
.pm = &bcmsdh_sdmmc_pm_ops,
},
#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) */
+#endif
};
struct sdos_info {
diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd.h b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd.h
index 5095aba..44fd410 100644
--- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd.h
+++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd.h
@@ -257,6 +257,7 @@ typedef struct dhd_pub {
int wlfc_enabled;
void* wlfc_state;
#endif
+ bool roam_env_detection;
bool dongle_isolation;
bool dongle_trap_occured;
int hang_was_sent;
@@ -700,6 +701,8 @@ extern char fw_down_path[MOD_PARAM_PATHLEN];
#define DHD_DEL_IF -0xe
#define DHD_BAD_IF -0xf
+#define WL_AUTO_ROAM_TRIGGER -75
+
#ifdef PROP_TXSTATUS
/* Please be mindful that total pkttag space is 32 octets only */
typedef struct dhd_pkttag {
diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cdc.c b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cdc.c
index 1610b7f..0cb4fb4 100644
--- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cdc.c
+++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cdc.c
@@ -69,6 +69,11 @@ typedef struct dhd_wlfc_commit_info {
} dhd_wlfc_commit_info_t;
#endif /* PROP_TXSTATUS */
+#ifdef VSDB_DYNAMIC_F2_BLKSIZE
+extern uint sd_f2_blocksize;
+extern int
+dhdsdio_func_blocksize(dhd_pub_t *dhd, int function_num, int block_size);
+#endif
typedef struct dhd_prot {
uint16 reqid;
uint8 pending;
@@ -458,10 +463,12 @@ dhd_wlfc_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
ea = interfaces[i].ea;
bcm_bprintf(strbuf, "INTERFACE[%d].ea = "
- "[%02x:%02x:%02x:%02x:%02x:%02x], if:%d, type: %s\n", i,
+ "[%02x:%02x:%02x:%02x:%02x:%02x], if:%d, type: %s"
+ "netif_flow_control:%s\n", i,
ea[0], ea[1], ea[2], ea[3], ea[4], ea[5],
interfaces[i].interface_id,
- iftype_desc);
+ iftype_desc, ((wlfc->hostif_flow_state[i] == OFF)
+ ? " OFF":" ON"));
bcm_bprintf(strbuf, "INTERFACE[%d].DELAYQ(len,state,credit)"
"= (%d,%s,%d)\n",
@@ -696,6 +703,32 @@ dhd_wlfc_hanger_get_free_slot(void* hanger)
}
static int
+dhd_wlfc_hanger_get_genbit(void* hanger, void* pkt, uint32 slot_id, int* gen)
+{
+ int rc = BCME_OK;
+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;
+
+ *gen = 0xff;
+
+ /* this packet was not pushed at the time it went to the firmware */
+ if (slot_id == WLFC_HANGER_MAXITEMS)
+ return BCME_NOTFOUND;
+
+ if (h) {
+ if ((h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE) ||
+ (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED)) {
+ *gen = h->items[slot_id].gen;
+ }
+ else {
+ rc = BCME_NOTFOUND;
+ }
+ }
+ else
+ rc = BCME_BADARG;
+ return rc;
+}
+
+static int
dhd_wlfc_hanger_pushpkt(void* hanger, void* pkt, uint32 slot_id)
{
int rc = BCME_OK;
@@ -729,13 +762,14 @@ dhd_wlfc_hanger_poppkt(void* hanger, uint32 slot_id, void** pktout, int remove_f
return BCME_NOTFOUND;
if (h) {
- if (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE) {
+ if (h->items[slot_id].state != WLFC_HANGER_ITEM_STATE_FREE) {
*pktout = h->items[slot_id].pkt;
if (remove_from_hanger) {
h->items[slot_id].state =
WLFC_HANGER_ITEM_STATE_FREE;
h->items[slot_id].pkt = NULL;
h->items[slot_id].identifier = 0;
+ h->items[slot_id].gen = 0xff;
h->popped++;
}
}
@@ -750,6 +784,29 @@ dhd_wlfc_hanger_poppkt(void* hanger, uint32 slot_id, void** pktout, int remove_f
}
static int
+dhd_wlfc_hanger_mark_suppressed(void* hanger, uint32 slot_id, uint8 gen)
+{
+ int rc = BCME_OK;
+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;
+
+ /* this packet was not pushed at the time it went to the firmware */
+ if (slot_id == WLFC_HANGER_MAXITEMS)
+ return BCME_NOTFOUND;
+ if (h) {
+ h->items[slot_id].gen = gen;
+ if (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE) {
+ h->items[slot_id].state = WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED;
+ }
+ else
+ rc = BCME_BADARG;
+ }
+ else
+ rc = BCME_BADARG;
+
+ return rc;
+}
+
+static int
_dhd_wlfc_pushheader(athost_wl_status_info_t* ctx, void* p, bool tim_signal,
uint8 tim_bmp, uint8 mac_handle, uint32 htodtag)
{
@@ -934,7 +991,9 @@ _dhd_wlfc_flow_control_check(athost_wl_status_info_t* ctx, struct pktq* pq, uint
pq->len, if_id, __FUNCTION__));
*/
WLFC_DBGMESG(("F"));
- /* dhd_txflowcontrol(ctx->dhdp, if_id, OFF); */
+#ifndef BCMDBUS
+ dhd_txflowcontrol(ctx->dhdp, if_id, OFF);
+#endif
ctx->toggle_host_if = 0;
}
if ((pq->len >= WLFC_FLOWCONTROL_HIWATER) && (ctx->hostif_flow_state[if_id] == OFF)) {
@@ -945,7 +1004,10 @@ _dhd_wlfc_flow_control_check(athost_wl_status_info_t* ctx, struct pktq* pq, uint
pq->len, if_id, __FUNCTION__));
*/
WLFC_DBGMESG(("N"));
- /* dhd_txflowcontrol(ctx->dhdp, if_id, ON); */
+ /* XXX: debug in progress */
+#ifndef BCMDBUS
+ dhd_txflowcontrol(ctx->dhdp, if_id, ON);
+#endif
ctx->host_ifidx = if_id;
ctx->toggle_host_if = 1;
}
@@ -1079,6 +1141,8 @@ _dhd_wlfc_pretx_pktprocess(athost_wl_status_info_t* ctx,
hslot = dhd_wlfc_hanger_get_free_slot(ctx->hanger);
free_ctr = WLFC_SEQCOUNT(entry, DHD_PKTTAG_FIFO(PKTTAG(p)));
DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), htod);
+ WLFC_PKTFLAG_SET_GENERATION(htod, entry->generation);
+ entry->transit_count++;
}
else {
hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
@@ -1089,7 +1153,7 @@ _dhd_wlfc_pretx_pktprocess(athost_wl_status_info_t* ctx,
DHD_PKTTAG_SETPKTDIR(PKTTAG(p), 1);
WL_TXSTATUS_SET_FLAGS(htod, WLFC_PKTFLAG_PKTFROMHOST);
WL_TXSTATUS_SET_FIFO(htod, DHD_PKTTAG_FIFO(PKTTAG(p)));
- WLFC_PKTFLAG_SET_GENERATION(htod, entry->generation);
+
if (!DHD_PKTTAG_CREDITCHECK(PKTTAG(p))) {
/*
@@ -1127,10 +1191,15 @@ _dhd_wlfc_pretx_pktprocess(athost_wl_status_info_t* ctx,
}
}
else {
+ int gen;
+
/* remove old header */
_dhd_wlfc_pullheader(ctx, p);
hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
+ dhd_wlfc_hanger_get_genbit(ctx->hanger, p, hslot, &gen);
+
+ WLFC_PKTFLAG_SET_GENERATION(htod, gen);
free_ctr = WLFC_PKTID_FREERUNCTR_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
/* push new header */
_dhd_wlfc_pushheader(ctx, p, send_tim_update,
@@ -1195,17 +1264,27 @@ _dhd_wlfc_deque_delayedq(athost_wl_status_info_t* ctx,
/* higher precedence will be picked up first,
i.e. suppressed packets before delayed ones
*/
- (NBITVAL((prec << 1) + 1) | NBITVAL((prec << 1))),
- &pout);
+ NBITVAL((prec << 1) + 1), &pout);
+ *needs_hdr = 0;
+
+ if (p == NULL) {
+ if (entry->suppressed == TRUE) {
+ if ((entry->suppr_transit_count <=
+ entry->suppress_count)) {
+ entry->suppressed = FALSE;
+ } else {
+ return NULL;
+ }
+ }
+ /* De-Q from delay Q */
+ p = pktq_mdeq(&entry->psq,
+ NBITVAL((prec << 1)),
+ &pout);
+ *needs_hdr = 1;
+ }
+
if (p != NULL) {
/* did the packet come from suppress sub-queue? */
- if (pout == ((prec << 1) + 1)) {
- /*
- this packet was suppressed and was sent on the bus
- previously; this already has a header
- */
- *needs_hdr = 0;
- }
if (entry->requested_credit > 0) {
entry->requested_credit--;
#ifdef PROP_TXSTATUS_DEBUG
@@ -1248,13 +1327,11 @@ _dhd_wlfc_deque_delayedq(athost_wl_status_info_t* ctx,
}
static void*
-_dhd_wlfc_deque_sendq(athost_wl_status_info_t* ctx, int prec, uint8* ac_credit_spent)
+_dhd_wlfc_deque_sendq(athost_wl_status_info_t* ctx, int prec)
{
wlfc_mac_descriptor_t* entry;
void* p;
- /* most cases a packet will count against FIFO credit */
- *ac_credit_spent = 1;
p = pktq_pdeq(&ctx->SENDQ, prec);
if (p != NULL) {
@@ -1269,7 +1346,7 @@ _dhd_wlfc_deque_sendq(athost_wl_status_info_t* ctx, int prec, uint8* ac_credit_s
return p;
}
- while ((p != NULL) && _dhd_wlfc_is_destination_closed(ctx, entry, prec)) {
+ while ((p != NULL)) {
/*
- suppressed packets go to sub_queue[2*prec + 1] AND
- delayed packets go to sub_queue[2*prec + 0] to ensure
@@ -1286,7 +1363,7 @@ _dhd_wlfc_deque_sendq(athost_wl_status_info_t* ctx, int prec, uint8* ac_credit_s
if applicable
*/
_dhd_wlfc_traffic_pending_check(ctx, entry, prec);
- _dhd_wlfc_flow_control_check(ctx, &entry->psq, DHD_PKTTAG_IF(PKTTAG(p)));
+
p = pktq_pdeq(&ctx->SENDQ, prec);
if (p == NULL)
break;
@@ -1297,23 +1374,6 @@ _dhd_wlfc_deque_sendq(athost_wl_status_info_t* ctx, int prec, uint8* ac_credit_s
return p;
}
}
- if (p) {
- if (entry->requested_packet == 0) {
- if (entry->requested_credit > 0)
- entry->requested_credit--;
- }
- else {
- entry->requested_packet--;
- DHD_PKTTAG_SETONETIMEPKTRQST(PKTTAG(p));
- }
- if (entry->state == WLFC_STATE_CLOSE)
- *ac_credit_spent = 0;
-#ifdef PROP_TXSTATUS_DEBUG
- entry->dstncredit_sent_packets++;
-#endif
- }
- if (p)
- _dhd_wlfc_flow_control_check(ctx, &ctx->SENDQ, DHD_PKTTAG_IF(PKTTAG(p)));
}
return p;
}
@@ -1444,41 +1504,13 @@ dhd_wlfc_enque_sendq(void* state, int prec, void* p)
}
int
-dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx)
+_dhd_wlfc_handle_packet_commit(athost_wl_status_info_t* ctx, int ac,
+ dhd_wlfc_commit_info_t *commit_info, f_commitpkt_t fcommit, void* commit_ctx)
{
- int ac;
- int credit;
- uint8 ac_fifo_credit_spent;
- uint8 needs_hdr;
uint32 hslot;
- void* p;
int rc;
- athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state;
- wlfc_mac_descriptor_t* mac_entry;
-
- if ((state == NULL) ||
- (fcommit == NULL)) {
- WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__));
- return BCME_BADARG;
- }
/*
- Commit packets for regular AC traffic. Higher priority first.
-
- -NOTE:
- If the bus between the host and firmware is overwhelmed by the
- traffic from host, it is possible that higher priority traffic
- starves the lower priority queue. If that occurs often, we may
- have to employ weighted round-robin or ucode scheme to avoid
- low priority packet starvation.
- */
- for (ac = AC_COUNT; ac >= 0; ac--) {
- for (credit = 0; credit < ctx->FIFO_credit[ac];) {
- p = _dhd_wlfc_deque_delayedq(ctx, ac, &ac_fifo_credit_spent, &needs_hdr,
- &mac_entry);
- if (p == NULL)
- break;
- /*
if ac_fifo_credit_spent = 0
This packet will not count against the FIFO credit.
@@ -1491,77 +1523,227 @@ dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx)
This is a normal packet and it counts against the FIFO
credit count.
*/
- DHD_PKTTAG_SETCREDITCHECK(PKTTAG(p), ac_fifo_credit_spent);
- rc = _dhd_wlfc_pretx_pktprocess(ctx, mac_entry, p, needs_hdr, &hslot);
+ DHD_PKTTAG_SETCREDITCHECK(PKTTAG(commit_info->p), commit_info->ac_fifo_credit_spent);
+ rc = _dhd_wlfc_pretx_pktprocess(ctx, commit_info->mac_entry, commit_info->p,
+ commit_info->needs_hdr, &hslot);
if (rc == BCME_OK)
- rc = fcommit(commit_ctx, p);
+ rc = fcommit(commit_ctx, commit_info->p);
else
ctx->stats.generic_error++;
if (rc == BCME_OK) {
ctx->stats.pkt2bus++;
- if (ac_fifo_credit_spent) {
+ if (commit_info->ac_fifo_credit_spent) {
ctx->stats.sendq_pkts[ac]++;
WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac);
- /*
- 1 FIFO credit has been spent by sending this packet
- to the device.
- */
- credit++;
}
}
else {
- /* bus commit has failed, rollback. */
- rc = _dhd_wlfc_rollback_packet_toq(ctx,
- p,
/*
+ bus commit has failed, rollback.
- remove wl-header for a delayed packet
- save wl-header header for suppressed packets
*/
- (needs_hdr ? eWLFC_PKTTYPE_DELAYED :
- eWLFC_PKTTYPE_SUPPRESSED),
- hslot);
+ rc = _dhd_wlfc_rollback_packet_toq(ctx, commit_info->p,
+ (commit_info->pkt_type), hslot);
if (rc != BCME_OK)
ctx->stats.rollback_failed++;
+
+ rc = BCME_ERROR;
+ }
+
+ return rc;
}
+
+int
+dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx)
+{
+ int ac;
+ int credit;
+ int rc;
+ dhd_wlfc_commit_info_t commit_info;
+ athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state;
+ int credit_count = 0;
+ int bus_retry_count = 0;
+ uint8 ac_available = 0; /* Bitmask for 4 ACs + BC/MC */
+
+ if ((state == NULL) ||
+ (fcommit == NULL)) {
+ WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__));
+ return BCME_BADARG;
}
- ctx->FIFO_credit[ac] -= credit;
- /* packets from SENDQ are fresh and they'd need header */
- needs_hdr = 1;
+
+ memset(&commit_info, 0, sizeof(commit_info));
+
+ /*
+ Commit packets for regular AC traffic. Higher priority first.
+ First, use up FIFO credits available to each AC. Based on distribution
+ and credits left, borrow from other ACs as applicable
+
+ -NOTE:
+ If the bus between the host and firmware is overwhelmed by the
+ traffic from host, it is possible that higher priority traffic
+ starves the lower priority queue. If that occurs often, we may
+ have to employ weighted round-robin or ucode scheme to avoid
+ low priority packet starvation.
+ */
+
+ for (ac = AC_COUNT; ac >= 0; ac--) {
+
+ int initial_credit_count = ctx->FIFO_credit[ac];
+
+ /* packets from SENDQ are fresh and they'd need header and have no MAC entry */
+ commit_info.needs_hdr = 1;
+ commit_info.mac_entry = NULL;
+ commit_info.pkt_type = eWLFC_PKTTYPE_NEW;
+
+ do {
+ commit_info.p = _dhd_wlfc_deque_sendq(ctx, ac);
+ if (commit_info.p == NULL)
+ break;
+ else if (ETHER_ISMULTI(DHD_PKTTAG_DSTN(PKTTAG(commit_info.p)))) {
+ ASSERT(ac == AC_COUNT);
+
+ if (ctx->FIFO_credit[ac]) {
+ rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info,
+ fcommit, commit_ctx);
+
+ /* Bus commits may fail (e.g. flow control); abort after retries */
+ if (rc == BCME_OK) {
+ if (commit_info.ac_fifo_credit_spent) {
+ (void) _dhd_wlfc_borrow_credit(ctx,
+ ac_available, ac);
+ credit_count--;
+ }
+ } else {
+ bus_retry_count++;
+ if (bus_retry_count >= BUS_RETRIES) {
+ DHD_ERROR((" %s: bus error\n",
+ __FUNCTION__));
+ return rc;
+ }
+ }
+ }
+ }
+
+ } while (commit_info.p);
+
for (credit = 0; credit < ctx->FIFO_credit[ac];) {
- p = _dhd_wlfc_deque_sendq(ctx, ac, &ac_fifo_credit_spent);
- if (p == NULL)
+ commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac,
+ &(commit_info.ac_fifo_credit_spent),
+ &(commit_info.needs_hdr),
+ &(commit_info.mac_entry));
+
+ if (commit_info.p == NULL)
break;
- DHD_PKTTAG_SETCREDITCHECK(PKTTAG(p), ac_fifo_credit_spent);
- rc = _dhd_wlfc_pretx_pktprocess(ctx, NULL, p, needs_hdr, &hslot);
- if (rc == BCME_OK)
- rc = fcommit(commit_ctx, p);
- else
- ctx->stats.generic_error++;
+ commit_info.pkt_type = (commit_info.needs_hdr) ? eWLFC_PKTTYPE_DELAYED :
+ eWLFC_PKTTYPE_SUPPRESSED;
+
+ rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info,
+ fcommit, commit_ctx);
+ /* Bus commits may fail (e.g. flow control); abort after retries */
if (rc == BCME_OK) {
- ctx->stats.pkt2bus++;
- if (ac_fifo_credit_spent) {
- WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac);
- ctx->stats.sendq_pkts[ac]++;
+ if (commit_info.ac_fifo_credit_spent) {
credit++;
}
}
else {
- /* bus commit has failed, rollback. */
- rc = _dhd_wlfc_rollback_packet_toq(ctx,
- p,
- /* remove wl-header while rolling back */
- eWLFC_PKTTYPE_NEW,
- hslot);
- if (rc != BCME_OK)
- ctx->stats.rollback_failed++;
+ bus_retry_count++;
+ if (bus_retry_count >= BUS_RETRIES) {
+ DHD_ERROR(("dhd_wlfc_commit_packets(): bus error\n"));
+ ctx->FIFO_credit[ac] -= credit;
+ return rc;
+ }
}
}
ctx->FIFO_credit[ac] -= credit;
+
+
+ /* If no credits were used, the queue is idle and can be re-used
+ Note that resv credits cannot be borrowed
+ */
+ if (initial_credit_count == ctx->FIFO_credit[ac]) {
+ ac_available |= (1 << ac);
+ credit_count += ctx->FIFO_credit[ac];
+ }
}
+
+ /* We borrow only for AC_BE and only if no other traffic seen for DEFER_PERIOD
+
+ Note that (ac_available & WLFC_AC_BE_TRAFFIC_ONLY) is done to:
+ a) ignore BC/MC for deferring borrow
+ b) ignore AC_BE being available along with other ACs
+ (this should happen only for pure BC/MC traffic)
+
+ i.e. AC_VI, AC_VO, AC_BK all MUST be available (i.e. no traffic) and
+ we do not care if AC_BE and BC/MC are available or not
+ */
+ if ((ac_available & WLFC_AC_BE_TRAFFIC_ONLY) == WLFC_AC_BE_TRAFFIC_ONLY) {
+
+ if (ctx->allow_credit_borrow) {
+ ac = 1; /* Set ac to AC_BE and borrow credits */
+ }
+ else {
+ int delta;
+ int curr_t = OSL_SYSUPTIME();
+
+ if (curr_t > ctx->borrow_defer_timestamp)
+ delta = curr_t - ctx->borrow_defer_timestamp;
+ else
+ delta = 0xffffffff + curr_t - ctx->borrow_defer_timestamp;
+
+ if (delta >= WLFC_BORROW_DEFER_PERIOD_MS) {
+ /* Reset borrow but defer to next iteration (defensive borrowing) */
+ ctx->allow_credit_borrow = TRUE;
+ ctx->borrow_defer_timestamp = 0;
+ }
+ return BCME_OK;
+ }
+ }
+ else {
+ /* If we have multiple AC traffic, turn off borrowing, mark time and bail out */
+ ctx->allow_credit_borrow = FALSE;
+ ctx->borrow_defer_timestamp = OSL_SYSUPTIME();
+ return BCME_OK;
+ }
+
+ /* At this point, borrow all credits only for "ac" (which should be set above to AC_BE)
+ Generically use "ac" only in case we extend to all ACs in future
+ */
+ for (; (credit_count > 0);) {
+
+ commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac,
+ &(commit_info.ac_fifo_credit_spent),
+ &(commit_info.needs_hdr),
+ &(commit_info.mac_entry));
+ if (commit_info.p == NULL)
+ break;
+
+ commit_info.pkt_type = (commit_info.needs_hdr) ? eWLFC_PKTTYPE_DELAYED :
+ eWLFC_PKTTYPE_SUPPRESSED;
+
+ rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info,
+ fcommit, commit_ctx);
+
+ /* Bus commits may fail (e.g. flow control); abort after retries */
+ if (rc == BCME_OK) {
+ if (commit_info.ac_fifo_credit_spent) {
+ (void) _dhd_wlfc_borrow_credit(ctx, ac_available, ac);
+ credit_count--;
+ }
+ }
+ else {
+ bus_retry_count++;
+ if (bus_retry_count >= BUS_RETRIES) {
+ DHD_ERROR(("dhd_wlfc_commit_packets(): bus error\n"));
+ return rc;
+ }
+ }
+ }
+
return BCME_OK;
}
@@ -1676,10 +1858,16 @@ dhd_wlfc_txstatus_update(dhd_pub_t *dhd, uint8* pkt_info)
return ret;
}
+ entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf);
+
if (!remove_from_hanger) {
/* this packet was suppressed */
-
- entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf);
+ if (!entry->suppressed || entry->generation != WLFC_PKTID_GEN(status)) {
+ entry->suppressed = TRUE;
+ entry->suppress_count = pktq_mlen(&entry->psq,
+ NBITVAL((WL_TXSTATUS_GET_FIFO(status) << 1) + 1));
+ entry->suppr_transit_count = entry->transit_count;
+ }
entry->generation = WLFC_PKTID_GEN(status);
}
@@ -1754,11 +1942,28 @@ dhd_wlfc_txstatus_update(dhd_pub_t *dhd, uint8* pkt_info)
/* indicate failure and free the packet */
dhd_txcomplete(dhd, pktbuf, FALSE);
+ entry->transit_count--;
+ /* This packet is transmitted Successfully by dongle even after first suppress. */
+ if (entry->suppressed){
+ entry->suppr_transit_count--;
+ }
PKTFREE(wlfc->osh, pktbuf, TRUE);
+ } else {
+ /* Mark suppressed to avoid a double free during wlfc cleanup */
+
+ dhd_wlfc_hanger_mark_suppressed(wlfc->hanger,
+ WLFC_PKTID_HSLOT_GET(status), WLFC_PKTID_GEN(status));
+ entry->suppress_count++;
}
}
else {
dhd_txcomplete(dhd, pktbuf, TRUE);
+ entry->transit_count--;
+
+ /* This packet is transmitted Successfully by dongle even after first suppress. */
+ if (entry->suppressed){
+ entry->suppr_transit_count--;
+ }
/* free the packet */
PKTFREE(wlfc->osh, pktbuf, TRUE);
}
@@ -2093,6 +2298,7 @@ dhd_wlfc_init(dhd_pub_t *dhd)
WLFC_FLAGS_RSSI_SIGNALS |
WLFC_FLAGS_XONXOFF_SIGNALS |
WLFC_FLAGS_CREDIT_STATUS_SIGNALS |
+ WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE |
WLFC_FLAGS_HOST_RXRERODER_ACTIVE : 0;
/* WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE | WLFC_FLAGS_HOST_RXRERODER_ACTIVE : 0; */
@@ -2168,7 +2374,9 @@ dhd_wlfc_enable(dhd_pub_t *dhd)
wlfc->allow_credit_borrow = TRUE;
wlfc->borrow_defer_timestamp = 0;
-
+#ifdef VSDB_DYNAMIC_F2_BLKSIZE
+ dhdsdio_func_blocksize(dhd, 2, VSDB_F2_BLKSIZE);
+#endif
return BCME_OK;
}
@@ -2210,8 +2418,9 @@ dhd_wlfc_cleanup(dhd_pub_t *dhd)
if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE) {
PKTFREE(wlfc->osh, h->items[i].pkt, TRUE);
h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE;
- h->items[i].pkt = NULL;
- h->items[i].identifier = 0;
+ } else if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED) {
+ /* These are freed from the psq so no need to free again */
+ h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE;
}
}
return;
@@ -2232,7 +2441,7 @@ dhd_wlfc_deinit(dhd_pub_t *dhd)
int i;
wlfc_hanger_t* h = (wlfc_hanger_t*)wlfc->hanger;
for (i = 0; i < h->max_items; i++) {
- if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE) {
+ if (h->items[i].state != WLFC_HANGER_ITEM_STATE_FREE) {
WLFC_DBGMESG(("%s() pkt[%d] = 0x%p, FIFO_credit_used:%d\n",
__FUNCTION__, i, h->items[i].pkt,
DHD_PKTTAG_CREDITCHECK(PKTTAG(h->items[i].pkt))));
@@ -2246,6 +2455,9 @@ dhd_wlfc_deinit(dhd_pub_t *dhd)
/* free top structure */
MFREE(dhd->osh, dhd->wlfc_state, sizeof(athost_wl_status_info_t));
dhd->wlfc_state = NULL;
+#ifdef VSDB_DYNAMIC_F2_BLKSIZE
+ dhdsdio_func_blocksize(dhd, 2, sd_f2_blocksize);
+#endif
return;
}
#endif /* PROP_TXSTATUS */
diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cfg80211.c b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cfg80211.c
index c0ef0bd..61369cb 100644
--- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cfg80211.c
@@ -507,7 +507,6 @@ int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command)
int i;
#endif
-
/* Figure out powermode 1 or o command */
strncpy((char *)&powermode_val, command + strlen("BTCOEXMODE") +1, 1);
WL_ERR(("%s: DHCP session Enter\n", __FUNCTION__));
diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_common.c b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_common.c
index f9f8c20..9fda3c1 100644
--- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_common.c
+++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_common.c
@@ -295,16 +295,17 @@ dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifindex, wl_ioctl_t *ioc, void *buf, int le
#ifdef CUSTOMER_HW_SAMSUNG
if (ret < 0) {
if (ioc->cmd == WLC_GET_VAR)
- DHD_ERROR(("%s: WLC_GET_VAR: %s, error = %d\n",
+ DHD_ERROR(("%s: WLC_GET_VAR: %s, ret = %d\n",
__FUNCTION__, (char *)ioc->buf, ret));
else if (ioc->cmd == WLC_SET_VAR)
- DHD_ERROR(("%s: WLC_SET_VAR: %s, error = %d\n",
+ DHD_ERROR(("%s: WLC_SET_VAR: %s, ret = %d\n",
__FUNCTION__, (char *)ioc->buf, ret));
else
- DHD_ERROR(("%s: WLC_IOCTL: cmd: %d, error = %d\n",
+ DHD_ERROR(("%s: WLC_IOCTL: cmd: %d, ret = %d\n",
__FUNCTION__, ioc->cmd, ret));
}
#endif /* CUSTOMER_HW_SAMSUNG */
+
return ret;
}
diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_custom_sec.c b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_custom_sec.c
index 4ef1dcb..74c5da3 100644
--- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_custom_sec.c
+++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_custom_sec.c
@@ -35,6 +35,7 @@ extern int _dhd_set_mac_address(struct dhd_info *dhd,
#define CIDINFO "/opt/etc/.cid.info"
#define PSMINFO "/opt/etc/.psm.info"
#define MACINFO "/opt/etc/.mac.info"
+#define MACINFO_EFS NULL
#define REVINFO "/data/.rev"
#else
#define MACINFO "/data/.mac.info"
@@ -585,14 +586,14 @@ int dhd_check_module_cid(dhd_pub_t *dhd)
ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
sizeof(cis_buf), 0, 0);
if (ret < 0) {
- DHD_ERROR(("%s: CIS reading failed, err=%d\n",
+ DHD_TRACE(("%s: CIS reading failed, err=%d\n",
__FUNCTION__, ret));
return ret;
} else {
#ifdef BCM4334_CHIP
unsigned char semco_id[4] = {0x00, 0x00, 0x33, 0x33};
unsigned char semco_id_sh[4] = {0x00, 0x00, 0xFB, 0x50}; //for SHARP FEM(new)
- DHD_ERROR(("%s: CIS reading success, err=%d\n",
+ DHD_ERROR(("%s: CIS reading success, ret=%d\n",
__FUNCTION__, ret));
#ifdef DUMP_CIS
dump_cis(cis_buf, 48);
@@ -725,7 +726,7 @@ int dhd_check_module_mac(dhd_pub_t *dhd)
ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
sizeof(cis_buf), 0, 0);
if (ret < 0) {
- DHD_ERROR(("%s: CIS reading failed, err=%d\n", __func__,
+ DHD_TRACE(("%s: CIS reading failed, err=%d\n", __func__,
ret));
return ret;
} else {
@@ -814,6 +815,11 @@ startwrite:
filp_close(fp_mac, NULL);
/* end of /data/.mac.info */
+ if (filepath_efs == NULL) {
+ DHD_ERROR(("[WIFI]%s : no efs filepath", __func__));
+ return 0;
+ }
+
/* File will be created /efs/wifi/.mac.info. */
fp_mac = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);
diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_linux.c b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_linux.c
index ca43dda..0cd3971 100644
--- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_linux.c
@@ -556,7 +556,7 @@ static int dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata,
static int dhd_sleep_pm_callback(struct notifier_block *nfb, unsigned long action, void *ignored)
{
int ret = NOTIFY_DONE;
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39))
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) || defined(BCMHOST)
switch (action) {
case PM_HIBERNATION_PREPARE:
case PM_SUSPEND_PREPARE:
@@ -1237,13 +1237,13 @@ dhd_op_if(dhd_if_t *ifp)
/* dhd_op_if is called again from some other context */
ifp->state = DHD_IF_DELETING;
if (ifp->net != NULL) {
- DHD_TRACE(("\n%s: got 'DHD_IF_DEL' state\n", __FUNCTION__));
+ DHD_ERROR(("\n%s: (WAR TRACE) got 'DHD_IF_DEL' state\n", __FUNCTION__));
+ netif_stop_queue(ifp->net);
#ifdef WL_CFG80211
if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) {
wl_cfg80211_notify_ifdel(ifp->net);
}
#endif
- netif_stop_queue(ifp->net);
unregister_netdev(ifp->net);
ret = DHD_DEL_IF; /* Make sure the free_netdev() is called */
}
@@ -1347,7 +1347,7 @@ _dhd_sysioc_thread(void *data)
}
if (dhd->set_macaddress == i+1) {
dhd->set_macaddress = 0;
- if (0 == _dhd_set_mac_address(dhd, i, &dhd->macvalue))
+ if (0 == _dhd_set_mac_address(dhd, i, &dhd->macvalue))
DHD_INFO(("dhd_sysioc_thread: MACID is overwritten\n"));
else
DHD_ERROR(("dhd_sysioc_thread: _dhd_set_mac_address() failed\n"));
@@ -1530,7 +1530,7 @@ dhd_start_xmit(struct sk_buff *skb, struct net_device *net)
* kernel panic issue when first bootup time,
* rmmod without interface down make unnecessary hang event.
*/
- if (dhd->pub.busstate == DHD_BUS_DOWN) {
+ if (dhd->pub.busstate == DHD_BUS_DOWN || dhd->pub.hang_was_sent) {
DHD_ERROR(("%s: xmit rejected pub.up=%d busstate=%d \n",
__FUNCTION__, dhd->pub.up, dhd->pub.busstate));
netif_stop_queue(net);
@@ -2363,8 +2363,17 @@ dhd_ethtool(dhd_info_t *dhd, void *uaddr)
static bool dhd_check_hang(struct net_device *net, dhd_pub_t *dhdp, int error)
{
+ dhd_info_t * dhd;
+
if (!dhdp)
return FALSE;
+
+ dhd = (dhd_info_t *)dhdp->info;
+ if (dhd->thr_sysioc_ctl.thr_pid <0) {
+ DHD_ERROR(("%s : skipped due to negative pid - unloading?\n", __FUNCTION__));
+ return FALSE;
+ }
+
if ((error == -ETIMEDOUT) || (error == -EREMOTEIO)
|| ((dhdp->busstate == DHD_BUS_DOWN)&&(!dhdp->dongle_reset))) {
DHD_ERROR(("%s: Event HANG send up due to re=%d te=%d e=%d s=%d\n", __FUNCTION__,
@@ -2612,7 +2621,7 @@ dhd_cleanup_virt_ifaces(dhd_info_t *dhd)
for (i = 1; i < DHD_MAX_IFS; i++) {
if (dhd->iflist[i]) {
- DHD_TRACE(("Deleting IF: %d \n", i));
+ DHD_ERROR(("(WAR TRACE)Deleting IF: %d \n", i));
if ((dhd->iflist[i]->state != DHD_IF_DEL) &&
(dhd->iflist[i]->state != DHD_IF_DELETING)) {
dhd->iflist[i]->state = DHD_IF_DEL;
@@ -2646,7 +2655,7 @@ dhd_stop(struct net_device *net)
int ifidx;
dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net);
DHD_OS_WAKE_LOCK(&dhd->pub);
- DHD_TRACE(("%s: Enter %p\n", __FUNCTION__, net));
+ DHD_TRACE(("%s: (WAR TRACE)Enter %p\n", __FUNCTION__, net));
if (dhd->pub.up == 0) {
goto exit;
}
@@ -3429,9 +3438,10 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
#ifdef CUSTOMER_HW_SAMSUNG
#ifdef ROAM_ENABLE
uint roamvar = 0;
- int roam_trigger[2] = {-75, WLC_BAND_ALL};
+ int roam_trigger[2] = {WL_AUTO_ROAM_TRIGGER, WLC_BAND_ALL};
int roam_scan_period[2] = {10, WLC_BAND_ALL};
int roam_delta[2] = {10, WLC_BAND_ALL};
+ int roam_env_mode = AP_ENV_INDETERMINATE;
#ifdef FULL_ROAMING_SCAN_PERIOD_60_SEC
int roam_fullscan_period = 60;
#else /* FULL_ROAMING_SCAN_PERIOD_60_SEC */
@@ -3639,6 +3649,13 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_DELTA, roam_delta, sizeof(roam_delta), TRUE, 0);
bcm_mkiovar("fullroamperiod", (char *)&roam_fullscan_period, 4, iovbuf, sizeof(iovbuf));
dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+ if (roam_trigger[0] == WL_AUTO_ROAM_TRIGGER) {
+ bcm_mkiovar("roam_env_detection", (char *)&roam_env_mode, 4, iovbuf, sizeof(iovbuf));
+ if (dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0) == BCME_OK)
+ dhd->roam_env_detection = TRUE;
+ else
+ dhd->roam_env_detection = FALSE;
+ }
#endif
#ifdef OKC_SUPPORT
@@ -3735,7 +3752,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
setbit(eventmask, WLC_E_MIC_ERROR);
setbit(eventmask, WLC_E_ASSOC_REQ_IE);
setbit(eventmask, WLC_E_ASSOC_RESP_IE);
+#ifndef WL_CFG80211
setbit(eventmask, WLC_E_PMKID_CACHE);
+#endif
setbit(eventmask, WLC_E_TXFAIL);
setbit(eventmask, WLC_E_JOIN_START);
setbit(eventmask, WLC_E_SCAN_COMPLETE);
@@ -3833,7 +3852,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
#endif /* defined(SOFTAP) */
if (dhd->pktfilter_count) {
int i;
-
+
for (i = 0; i < dhd->pktfilter_count; i++)
dhd_pktfilter_offload_set(dhd, dhd->pktfilter[i]);
}
@@ -5089,7 +5108,7 @@ int net_os_set_packet_filter(struct net_device *dev, int val)
for (i = 0; i < dhd->pub.pktfilter_count; i++)
dhd_pktfilter_offload_enable(&dhd->pub, dhd->pub.pktfilter[i],
val, dhd_master_mode);
- }
+ }
}
}
return ret;
@@ -5375,7 +5394,7 @@ int dhd_os_wake_lock(dhd_pub_t *pub)
wake_lock(&dhd->wl_wifi);
#elif defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP)
/*SLP_wakelock_alternative_code*/
- pm_stay_awake(pm_dev);
+ pm_stay_awake(pm_dev);
#endif
dhd->wakelock_counter++;
ret = dhd->wakelock_counter;
@@ -5410,7 +5429,7 @@ int dhd_os_wake_unlock(dhd_pub_t *pub)
wake_unlock(&dhd->wl_wifi);
#elif defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP)
/*SLP_wakelock_alternative_code*/
- pm_relax(pm_dev);
+ pm_relax(pm_dev);
#endif
ret = dhd->wakelock_counter;
}
@@ -5438,7 +5457,7 @@ int dhd_os_check_wakelock(void *dhdp)
if (!pub)
return 0;
- dhd = (dhd_info_t *)(pub->info);
+ dhd = (dhd_info_t *)(pub->info);
DHD_ERROR(("%s : wakelock_count = %d\n", __func__, dhd->wakelock_counter ));
diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sdio.c b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sdio.c
index 052eaaf..211c865 100644
--- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sdio.c
+++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sdio.c
@@ -179,6 +179,8 @@ char fw_down_path[MOD_PARAM_PATHLEN];
#define MIN_RSRC_SR 0x3
#define CORE_CAPEXT_ADDR (SI_ENUM_BASE + 0x64c)
#define CORE_CAPEXT_SR_SUPPORTED_MASK (1 << 1)
+#define RCTL_MACPHY_DISABLE_MASK (1 << 26)
+#define RCTL_LOGIC_DISABLE_MASK (1 << 27)
#define OOB_WAKEUP_ENAB(bus) ((bus)->_oobwakeup)
#define GPIO_DEV_SRSTATE 16 /* Host gpio17 mapped to device gpio0 SR state */
@@ -609,22 +611,21 @@ static bool
dhdsdio_sr_cap(dhd_bus_t *bus)
{
bool cap = FALSE;
- uint32 min = 0, core_capext;
+ uint32 min = 0, core_capext, data;
core_capext = bcmsdh_reg_read(bus->sdh, CORE_CAPEXT_ADDR, 4);
if (!(core_capext & CORE_CAPEXT_SR_SUPPORTED_MASK))
return FALSE;
+ if (bus->sih->chip == BCM4324_CHIP_ID) {
min = bcmsdh_reg_read(bus->sdh, MIN_RSRC_ADDR, 4);
- if (min == MIN_RSRC_SR) {
+ if (min == MIN_RSRC_SR)
cap = TRUE;
-
- if ((bus->sih->chip == BCM4334_CHIP_ID) && (bus->sih->chiprev < 3)) {
- cap = FALSE;
-
- DHD_ERROR(("Only 4334 >= B2 supports SR: curr rev %d\n",
- bus->sih->chiprev));
- }
+ } else {
+ data = bcmsdh_reg_read(bus->sdh,
+ SI_ENUM_BASE + OFFSETOF(chipcregs_t, retention_ctl), 4);
+ if ((data & (RCTL_MACPHY_DISABLE_MASK | RCTL_LOGIC_DISABLE_MASK)) == 0)
+ cap = TRUE;
}
return cap;
@@ -1313,6 +1314,38 @@ dhdsdio_bussleep(dhd_bus_t *bus, bool sleep)
return err;
}
+#ifdef VSDB_DYNAMIC_F2_BLKSIZE
+int
+dhdsdio_func_blocksize(dhd_pub_t *dhd, int function_num, int block_size)
+{
+ int func_blk_size = function_num;
+ int bcmerr = 0;
+ int result;
+
+ bcmerr = dhd_bus_iovar_op(dhd, "sd_blocksize", &func_blk_size, sizeof(int), &result, sizeof(int), 0);
+
+ if (bcmerr != BCME_OK) {
+ DHD_ERROR(("%s: Get F%d Block size error\n", __FUNCTION__, function_num));
+ return BCME_ERROR;
+ }
+
+ if (result != block_size) {
+
+ DHD_ERROR(("%s: F%d Block size set from %d to %d\n", __FUNCTION__, function_num, result, block_size));
+
+ func_blk_size = function_num << 16 | block_size ;
+ bcmerr = dhd_bus_iovar_op(dhd, "sd_blocksize", &func_blk_size, sizeof(int32), &result, sizeof(int32), 1);
+
+ if (bcmerr != BCME_OK) {
+ DHD_ERROR(("%s: Set F2 Block size error\n", __FUNCTION__));
+ return BCME_ERROR;
+ }
+ }
+
+ return BCME_OK;
+
+}
+#endif
#if defined(OOB_INTR_ONLY)
void
dhd_enable_oob_intr(struct dhd_bus *bus, bool enable)
@@ -1955,10 +1988,10 @@ dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen)
#endif
#endif /* DHD_DEBUG */
} else if (pending == TRUE) {
- DHD_CTL(("%s: canceled\n", __FUNCTION__));
+ DHD_ERROR(("%s: canceled\n", __FUNCTION__));
return -ERESTARTSYS;
} else {
- DHD_CTL(("%s: resumed for unknown reason?\n", __FUNCTION__));
+ DHD_ERROR(("%s: resumed for unknown reason?\n", __FUNCTION__));
#ifdef DHD_DEBUG
dhd_os_sdlock(bus->dhd);
dhdsdio_checkdied(bus, NULL, 0);
@@ -3942,7 +3975,10 @@ dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq)
uint8 *dptr, num = 0;
uint16 sublen, check;
- void *pfirst, *plast, *pnext, *save_pfirst;
+ void *pfirst, *plast, *pnext;
+ void * list_tail[DHD_MAX_IFS] = { NULL };
+ void * list_head[DHD_MAX_IFS] = { NULL };
+ uint8 idx;
osl_t *osh = bus->dhd->osh;
int errcode;
@@ -4231,7 +4267,6 @@ dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq)
}
/* Basic SD framing looks ok - process each packet (header) */
- save_pfirst = pfirst;
bus->glom = NULL;
plast = NULL;
@@ -4274,9 +4309,6 @@ dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq)
PKTFREE(bus->dhd->osh, pfirst, FALSE);
if (plast) {
PKTSETNEXT(osh, plast, pnext);
- } else {
- ASSERT(save_pfirst == pfirst);
- save_pfirst = pnext;
}
continue;
} else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pfirst, reorder_info_buf,
@@ -4286,9 +4318,6 @@ dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq)
PKTFREE(osh, pfirst, FALSE);
if (plast) {
PKTSETNEXT(osh, plast, pnext);
- } else {
- ASSERT(save_pfirst == pfirst);
- save_pfirst = pnext;
}
continue;
}
@@ -4304,9 +4333,6 @@ dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq)
if (free_buf_count == 0) {
if (plast) {
PKTSETNEXT(osh, plast, pnext);
- } else {
- ASSERT(save_pfirst == pfirst);
- save_pfirst = pnext;
}
continue;
}
@@ -4319,15 +4345,14 @@ dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq)
temp = PKTNEXT(osh, temp);
}
pfirst = temp;
- if (plast) {
- PKTSETNEXT(osh, plast, ppfirst);
+ if (list_tail[ifidx] == NULL) {
+ list_head[ifidx] = ppfirst;
+ list_tail[ifidx] = pfirst;
}
else {
- /* first one in the chain */
- save_pfirst = ppfirst;
+ PKTSETNEXT(osh, list_tail[ifidx], ppfirst);
+ list_tail[ifidx] = pfirst;
}
-
- PKTSETNEXT(osh, pfirst, pnext);
plast = pfirst;
}
@@ -4335,8 +4360,14 @@ dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq)
}
else {
/* this packet will go up, link back into chain and count it */
- PKTSETNEXT(osh, pfirst, pnext);
plast = pfirst;
+ if (list_tail[ifidx] == NULL) {
+ list_head[ifidx] = list_tail[ifidx] = pfirst;
+ }
+ else {
+ PKTSETNEXT(osh, list_tail[ifidx], pfirst);
+ list_tail[ifidx] = pfirst;
+ }
num++;
}
#ifdef DHD_DEBUG
@@ -4351,12 +4382,22 @@ dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq)
#endif /* DHD_DEBUG */
}
dhd_os_sdunlock_rxq(bus->dhd);
- if (num) {
- dhd_os_sdunlock(bus->dhd);
- dhd_rx_frame(bus->dhd, ifidx, save_pfirst, num, 0);
- dhd_os_sdlock(bus->dhd);
+ for (idx = 0; idx < DHD_MAX_IFS; idx++) {
+ if (list_head[idx]) {
+ void *temp;
+ uint8 cnt = 0;
+ temp = list_head[idx];
+ do {
+ temp = PKTNEXT(osh, temp);
+ cnt++;
+ } while (temp);
+ if (cnt) {
+ dhd_os_sdunlock(bus->dhd);
+ dhd_rx_frame(bus->dhd, idx, list_head[idx], cnt, 0);
+ dhd_os_sdlock(bus->dhd);
+ }
+ }
}
-
bus->rxglomframes++;
bus->rxglompkts += num;
}
@@ -5805,7 +5846,7 @@ dhd_bus_watchdog(dhd_pub_t *dhdp)
} else
dhdsdio_clkctl(bus, CLK_NONE, FALSE);
- bus->idlecount = 0;
+ bus->idlecount = 0;
}
}
#else
@@ -6130,7 +6171,7 @@ dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot,
#ifdef BCMHOST_XTAL_PU_TIME_MOD
#ifdef BCM4334_CHIP
bcmsdh_reg_write(bus->sdh, 0x18000620, 2, 11);
- bcmsdh_reg_write(bus->sdh, 0x18000628, 4, 0x00A60001);
+ bcmsdh_reg_write(bus->sdh, 0x18000628, 4, 0x00F80001);
#endif
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sec_feature.h b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sec_feature.h
index 2d1d200..d6bb7f0 100644
--- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sec_feature.h
+++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sec_feature.h
@@ -49,11 +49,20 @@
#define WRITE_MACADDR
#endif
+#ifdef CONFIG_ARCH_MSM7X30
+#define HW_OOB
+#define READ_MACADDR
+#endif
+
#ifdef CONFIG_MACH_GC1
#undef USE_CID_CHECK
#define READ_MACADDR
#endif
+#ifdef CONFIG_MACH_P10
+#define READ_MACADDR
+#endif
+
/* REGION CODE */
#if (WLAN_REGION_CODE >= 100) && (WLAN_REGION_CODE < 200) /*EUR*/
@@ -89,7 +98,7 @@
#undef WRITE_MACADDR
#undef READ_MACADDR
#ifdef CONFIG_BCM4334
-#define RDWR_KORICS_MACADDR
+#define READ_MACADDR
#else
#define RDWR_MACADDR
#endif
@@ -115,3 +124,4 @@
#if !defined(READ_MACADDR) && !defined(WRITE_MACADDR) && !defined(RDWR_KORICS_MACADDR) && !defined(RDWR_MACADDR)
#define GET_MAC_FROM_OTP
#endif
+
diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_wlfc.h b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_wlfc.h
index c8b3181..308e318 100644
--- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_wlfc.h
+++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_wlfc.h
@@ -29,6 +29,7 @@
#define WLFC_HANGER_ITEM_STATE_FREE 1
#define WLFC_HANGER_ITEM_STATE_INUSE 2
+#define WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED 3
#define WLFC_PKTID_HSLOT_MASK 0xffff /* allow 16 bits only */
#define WLFC_PKTID_HSLOT_SHIFT 8
@@ -68,7 +69,8 @@ typedef enum ewlfc_mac_entry_action {
typedef struct wlfc_hanger_item {
uint8 state;
- uint8 pad[3];
+ uint8 gen;
+ uint8 pad[2];
uint32 identifier;
void* pkt;
#ifdef PROP_TXSTATUS_DEBUG
@@ -93,12 +95,12 @@ typedef struct wlfc_hanger {
#define WLFC_STATE_CLOSE 2
#define WLFC_PSQ_PREC_COUNT ((AC_COUNT + 1) * 2) /* 2 for each AC traffic and bc/mc */
-#define WLFC_PSQ_LEN 64
-#define WLFC_SENDQ_LEN 256
+#define WLFC_PSQ_LEN 2048
+#define WLFC_SENDQ_LEN 256 /* XXX: Match dhd_sdio txq length */
+
+#define WLFC_FLOWCONTROL_HIWATER (2048 - 256)
+#define WLFC_FLOWCONTROL_LOWATER 256
-#define WLFC_FLOWCONTROL_DELTA 8
-#define WLFC_FLOWCONTROL_HIWATER (WLFC_PSQ_LEN - WLFC_FLOWCONTROL_DELTA)
-#define WLFC_FLOWCONTROL_LOWATER (WLFC_FLOWCONTROL_HIWATER - WLFC_FLOWCONTROL_DELTA)
typedef struct wlfc_mac_descriptor {
uint8 occupied;
@@ -123,6 +125,11 @@ typedef struct wlfc_mac_descriptor {
/* 1= send on next opportunity */
uint8 send_tim_signal;
uint8 mac_handle;
+ uint transit_count;
+ uint suppr_transit_count;
+ uint suppress_count;
+ uint8 suppressed;
+
#ifdef PROP_TXSTATUS_DEBUG
uint32 dstncredit_sent_packets;
uint32 dstncredit_acks;
diff --git a/drivers/net/wireless/bcmdhd/src/include/epivers.h b/drivers/net/wireless/bcmdhd/src/include/epivers.h
index 8be59f6..4e873bb 100644
--- a/drivers/net/wireless/bcmdhd/src/include/epivers.h
+++ b/drivers/net/wireless/bcmdhd/src/include/epivers.h
@@ -30,19 +30,19 @@
#define EPI_MINOR_VERSION 15
-#define EPI_RC_NUMBER 12
+#define EPI_RC_NUMBER 15
#define EPI_INCREMENTAL_NUMBER 0
#define EPI_BUILD_NUMBER 0
-#define EPI_VERSION 1, 15, 12, 0
+#define EPI_VERSION 1, 15, 15, 0
-#define EPI_VERSION_NUM 0x010f0900
+#define EPI_VERSION_NUM 0x010f0f00
-#define EPI_VERSION_DEV 1.15.12
+#define EPI_VERSION_DEV 1.15.15
-#define EPI_VERSION_STR "1.15.12"
+#define EPI_VERSION_STR "1.15.15"
#endif /* _epivers_h_ */
diff --git a/drivers/net/wireless/bcmdhd/src/include/sbchipc.h b/drivers/net/wireless/bcmdhd/src/include/sbchipc.h
index e6a76b8..03039a6 100644
--- a/drivers/net/wireless/bcmdhd/src/include/sbchipc.h
+++ b/drivers/net/wireless/bcmdhd/src/include/sbchipc.h
@@ -289,7 +289,11 @@ typedef volatile struct {
uint32 pllcontrol_data;
uint32 pmustrapopt;
uint32 pmu_xtalfreq;
- uint32 PAD[100];
+ uint32 retention_ctl;
+ uint32 PAD[3];
+ uint32 retention_grpidx;
+ uint32 retention_grpctl;
+ uint32 PAD[94];
uint16 sromotp[512];
uint32 nand_revision;
diff --git a/drivers/net/wireless/bcmdhd/src/include/wlioctl.h b/drivers/net/wireless/bcmdhd/src/include/wlioctl.h
index 72a54ce..d6bdb8f 100644
--- a/drivers/net/wireless/bcmdhd/src/include/wlioctl.h
+++ b/drivers/net/wireless/bcmdhd/src/include/wlioctl.h
@@ -1867,6 +1867,12 @@ typedef struct wl_po {
#define WLAN_AUTO_W_NOISE 4 /* ACI: auto - detect and non 802.11 interference */
#define AUTO_ACTIVE (1 << 7) /* Auto is currently active */
+/* AP environment */
+#define AP_ENV_DETECT_NOT_USED 0 /* We aren't using AP environment detection */
+#define AP_ENV_DENSE 1 /* "Corporate" or other AP dense environment */
+#define AP_ENV_SPARSE 2 /* "Home" or other sparse environment */
+#define AP_ENV_INDETERMINATE 3 /* AP environment hasn't been identified */
+
typedef struct wl_aci_args {
int enter_aci_thresh; /* Trigger level to start detecting ACI */
int exit_aci_thresh; /* Trigger level to exit ACI mode */
diff --git a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c
index 49782c5..7f1b86c 100644
--- a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c
+++ b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c
@@ -129,9 +129,10 @@ typedef struct cmd_tlv {
#define CMD_OKC_ENABLE "OKC_ENABLE"
#endif
-#ifdef BCM4334_CHIP //ampdu_mpdu
+#ifdef SUPPORT_AMPDU_MPDU_CMD
#define CMD_AMPDU_MPDU "AMPDU_MPDU"
#endif
+
#ifdef VSDB
#define CMD_CHANGE_RL "CHANGE_RL"
#define CMD_RESTORE_RL "RESTORE_RL"
@@ -234,11 +235,11 @@ static int wl_android_set_suspendopt(struct net_device *dev, char *command, int
if (!dhd_download_fw_on_driverload) {
#endif /* CUSTOMER_HW_SAMSUNG */
suspend_flag = *(command + strlen(CMD_SETSUSPENDOPT) + 1) - '0';
-
+
if (suspend_flag != 0)
suspend_flag = 1;
ret_now = net_os_set_suspend_disable(dev, suspend_flag);
-
+
if (ret_now != suspend_flag) {
if (!(ret = net_os_set_suspend(dev, ret_now)))
DHD_INFO(("%s: Suspend Flag %d -> %d\n",
@@ -407,13 +408,9 @@ static int wl_android_get_country_rev(
__func__, error));
return -1;
} else {
- DHD_INFO(("%s: get country '%c%c %d'\n",
- __func__, cspec.ccode[0], cspec.ccode[1], cspec.rev));
+ DHD_INFO(("%s: get country '%s %d'\n", __func__, smbuf, smbuf[WLC_CNTRY_BUF_SZ]));
}
-
- bytes_written = snprintf(command, total_len, "%c%c %d",
- cspec.ccode[0], cspec.ccode[1], cspec.rev);
-
+ bytes_written = snprintf(command, total_len, "%s %s %d", CMD_COUNTRYREV_GET, smbuf, smbuf[WLC_CNTRY_BUF_SZ]);
return bytes_written;
}
#endif /* ROAM_API */
@@ -706,20 +703,6 @@ static int wl_android_set_fwpath(struct net_device *net, char *command, int tota
return 0;
}
-static int my_atoi(const char *string_num)
-{
- int int_val=0;
- for(;; string_num++) {
- switch (*string_num) {
- case '0'...'9' :
- int_val = 10 * int_val + (*string_num-'0');
- break;
- default:
- return int_val;
- }
- }
- return int_val;
-}
static int
wl_android_set_auto_channel(struct net_device *dev, const char* string_num,
@@ -737,7 +720,7 @@ wl_android_set_auto_channel(struct net_device *dev, const char* string_num,
/* Auto channel select */
wl_uint32_list_t request;
- channel = my_atoi(string_num);
+ channel = bcm_atoi(string_num);
DHD_INFO(("%s : HAPD_AUTO_CHANNEL = %d\n", __FUNCTION__, channel));
if (channel == 20)
@@ -794,7 +777,7 @@ wl_android_set_max_num_sta(struct net_device *dev, const char* string_num)
{
int max_assoc;
- max_assoc = my_atoi(string_num);
+ max_assoc = bcm_atoi(string_num);
DHD_INFO(("%s : HAPD_MAX_NUM_STA = %d\n", __FUNCTION__, max_assoc));
wldev_iovar_setint(dev, "maxassoc", max_assoc);
return 1;
@@ -823,7 +806,7 @@ wl_android_set_hide_ssid(struct net_device *dev, const char* string_num)
int hide_ssid;
int enable = 0;
- hide_ssid = my_atoi(string_num);
+ hide_ssid = bcm_atoi(string_num);
DHD_INFO(("%s: HAPD_HIDE_SSID = %d\n", __FUNCTION__, hide_ssid));
if (hide_ssid)
enable = 1;
@@ -926,7 +909,8 @@ wl_android_ch_res_rl(struct net_device *dev, bool change)
}
#endif
-#ifdef BCM4334_CHIP //ampdu_mpdu
+#ifdef SUPPORT_AMPDU_MPDU_CMD
+/* CMD_AMPDU_MPDU */
static int
wl_android_set_ampdu_mpdu(struct net_device *dev, const char* string_num)
{
@@ -946,7 +930,7 @@ wl_android_set_ampdu_mpdu(struct net_device *dev, const char* string_num)
DHD_ERROR(("%s : ampdu_mpdu set error. %d\n", __FUNCTION__, err));
return -1;
}
-
+
return 0;
}
#endif
@@ -1060,6 +1044,7 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
else if (strnicmp(command, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) {
uint band = *(command + strlen(CMD_SETBAND) + 1) - '0';
bytes_written = wldev_set_band(net, band);
+ wl_update_wiphybands(NULL);
}
else if (strnicmp(command, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) {
bytes_written = wl_android_get_band(net, command, priv_cmd.total_len);
@@ -1189,7 +1174,8 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
bytes_written = wl_android_get_assoc_res_ies(net, command);
}
#endif /* BCMCCX */
-#ifdef BCM4334_CHIP //ampdu_mpdu
+#ifdef SUPPORT_AMPDU_MPDU_CMD
+ /* CMD_AMPDU_MPDU */
else if (strnicmp(command, CMD_AMPDU_MPDU,strlen(CMD_AMPDU_MPDU)) == 0) {
int skip = strlen(CMD_AMPDU_MPDU) + 1;
bytes_written = wl_android_set_ampdu_mpdu(net, (const char*)command+skip);
@@ -1426,6 +1412,10 @@ int dhd_os_check_wakelock(void *dhdp);
static int wifi_suspend(struct platform_device *pdev, pm_message_t state)
{
DHD_TRACE(("##> %s\n", __FUNCTION__));
+#if defined(BCMHOST)
+ if (dhd_os_check_wakelock(bcmsdh_get_drvdata()))
+ return -EBUSY;
+#endif
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) && 1
bcmsdh_oob_intr_set(0);
#endif /* (OOB_INTR_ONLY) */
diff --git a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.c
index c74adcc..e3bb3e4 100644
--- a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.c
@@ -63,7 +63,7 @@
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
#define DAEMONIZE(a) daemonize(a); \
allow_signal(SIGKILL); \
- allow_signal(SIGTERM);
+allow_signal(SIGTERM);
#else /* Linux 2.4 (w/o preemption patch) */
#define DAEMONIZE(a) daemonize(); \
do { if (a) \
@@ -144,6 +144,8 @@ u32 wl_dbg_level = WL_DBG_ERR;
#define DNGL_FUNC(func, parameters) func parameters;
#define COEX_DHCP
+#define WLAN_EID_SSID 0
+
/* Set this to 1 to use a seperate interface (p2p0)
* for p2p operations.
*/
@@ -370,8 +372,8 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *dev);
static void wl_free_wdev(struct wl_priv *wl);
static s32 wl_inform_bss(struct wl_priv *wl);
-static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
-static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev);
+static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi, u8 is_roam_done);
+static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev, u8 is_roam_done);
static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy);
static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
@@ -2167,11 +2169,32 @@ scan_out:
err = -EBUSY;
}
- /*if continuous busy state , abort scan */
+#define SCAN_EBUSY_RETRY_LIMIT 10
if (err == -EBUSY) {
- if (busy_count++ > 5) {
+ if (busy_count++ > SCAN_EBUSY_RETRY_LIMIT) {
+ struct ether_addr bssid;
+ s32 ret = 0;
busy_count = 0;
- wl_cfg80211_scan_abort(wl, ndev);
+ WL_ERR(("Unusual continuous EBUSY error, %d %d %d %d %d %d %d %d %d\n",
+ wl_get_drv_status(wl, SCANNING, ndev),
+ wl_get_drv_status(wl, SCAN_ABORTING, ndev),
+ wl_get_drv_status(wl, CONNECTING, ndev),
+ wl_get_drv_status(wl, CONNECTED, ndev),
+ wl_get_drv_status(wl, DISCONNECTING, ndev),
+ wl_get_drv_status(wl, AP_CREATING, ndev),
+ wl_get_drv_status(wl, AP_CREATED, ndev),
+ wl_get_drv_status(wl, SENDING_ACT_FRM, ndev),
+ wl_get_drv_status(wl, SENDING_ACT_FRM, ndev)));
+
+ bzero(&bssid, sizeof(bssid));
+ if ((ret = wldev_ioctl(ndev, WLC_GET_BSSID,
+ &bssid, ETHER_ADDR_LEN, false)) == 0)
+ WL_ERR(("FW is connected with " MACSTR "/n",
+ MAC2STR(bssid.octet)));
+ else
+ WL_ERR(("GET BSSID failed with %d\n", ret));
+
+ wl_cfg80211_disconnect(wiphy, ndev, DOT11_RC_DISASSOC_LEAVING);
}
} else {
busy_count = 0;
@@ -2771,6 +2794,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
wl_extjoin_params_t *ext_join_params;
struct wl_join_params join_params;
size_t join_params_size;
+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
s32 err = 0;
wpa_ie_fixed_t *wpa_ie;
wpa_ie_fixed_t *wps_ie;
@@ -2920,7 +2944,15 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
return err;
}
}
-
+ if (dhd->roam_env_detection && (wldev_iovar_setint(dev, "roam_env_detection",
+ AP_ENV_DETECT_NOT_USED) == BCME_OK)) {
+ s32 roam_trigger[2] = {WL_AUTO_ROAM_TRIGGER, WLC_BAND_ALL};
+ err = wldev_ioctl(dev, WLC_SET_ROAM_TRIGGER, roam_trigger,
+ sizeof(roam_trigger), true);
+ if (unlikely(err)) {
+ WL_ERR((" failed to restore roam_trigger for auto env detection\n"));
+ }
+ }
if (chan) {
#ifdef ROAM_CHANNEL_CACHE
wlc_ssid_t ssid;
@@ -3567,7 +3599,7 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
WL_DBG((" Enter\n"));
if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP) {
err = wldev_iovar_getbuf(dev, "sta_info", (struct ether_addr *)mac,
- ETHER_ADDR_LEN, wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
+ ETHER_ADDR_LEN, wl->ioctl_buf, WLC_IOCTL_SMLEN, &wl->ioctl_buf_sync);
if (err < 0) {
WL_ERR(("GET STA INFO failed, %d\n", err));
return err;
@@ -4542,10 +4574,13 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
memcpy(wl->afx_hdl->tx_dst_addr.octet,
af_params->action_frame.da.octet,
sizeof(wl->afx_hdl->tx_dst_addr.octet));
- if ((act_frm->subtype == P2P_PAF_PROVDIS_REQ) &&
- (p2p_ie = wl_cfgp2p_find_p2pie((u8 *)act_frm->elts, action_frame->len)) != NULL) {
- if ((ptr = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_GROUP_ID))) {
- is_PROVDIS_REQ_GO = true;
+ if (act_frm && act_frm->elts) {
+ if ((act_frm->subtype == P2P_PAF_PROVDIS_REQ) &&
+ (p2p_ie = wl_cfgp2p_find_p2pie((u8 *)act_frm->elts,
+ action_frame->len)) != NULL) {
+ if ((ptr = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_GROUP_ID))) {
+ is_PROVDIS_REQ_GO = true;
+ }
}
}
@@ -5535,7 +5570,7 @@ static s32 wl_inform_bss(struct wl_priv *wl)
#ifdef ROAM_CHANNEL_CACHE
add_roam_cache(bi);
#endif
- err = wl_inform_single_bss(wl, bi);
+ err = wl_inform_single_bss(wl, bi, 0);
if (unlikely(err))
break;
}
@@ -5545,7 +5580,7 @@ static s32 wl_inform_bss(struct wl_priv *wl)
return err;
}
-static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
+static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi, u8 is_roam_done)
{
struct wiphy *wiphy = wiphy_from_scan(wl);
struct ieee80211_mgmt *mgmt;
@@ -5559,6 +5594,7 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
s32 signal;
u32 freq;
s32 err = 0;
+ u8 * ie_offset = NULL;
gfp_t aflags;
if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) {
@@ -5586,7 +5622,7 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
return err;
}
- notif_bss_info->rssi = dtoh16(bi->RSSI);
+ notif_bss_info->rssi = dtoh16(bi->RSSI) + RSSI_OFFSET;
memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN);
mgmt_type = wl->active_scan ?
IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON;
@@ -5601,7 +5637,35 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
beacon_proberesp->capab_info = cpu_to_le16(bi->capability);
wl_rst_ie(wl);
- wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
+ ie_offset = ((u8 *) bi) + bi->ie_offset;
+
+ if (is_roam_done && ((int)(*(ie_offset)) == WLAN_EID_SSID &&
+ ((int)(*(ie_offset+1)) == 0 || (int)(*(ie_offset+2)) == 0))) {
+ u8 *ie_new_offset = NULL;
+ uint8 ie_new_length;
+
+ WL_ERR(("WAR trace: Changing the SSID Info, from beacon %d\n", bi->flags & WL_BSS_FLAGS_FROM_BEACON));
+
+ ie_new_offset = (u8 *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
+ if (ie_new_offset) {
+ *(ie_new_offset) = WLAN_EID_SSID;
+ *(ie_new_offset+1) = bi->SSID_len;
+ memcpy(ie_new_offset+2, bi->SSID, bi->SSID_len);
+ ie_new_length = bi->ie_length - *(ie_offset+1) + bi->SSID_len;
+
+ /* Copy the remaining IE apart from SSID IE from bi */
+ memcpy( ie_new_offset+2 + bi->SSID_len,
+ ie_offset+2 + *(ie_offset+1),
+ bi->ie_length - 2 - *(ie_offset+1));
+ wl_mrg_ie(wl, ie_new_offset , ie_new_length);
+ kfree(ie_new_offset);
+ } else {
+ wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
+ }
+ } else {
+ wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
+ }
+
wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
offsetof(struct wl_cfg80211_bss_info, frame_buf));
notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt,
@@ -5626,21 +5690,6 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
notif_bss_info->frame_len));
signal = notif_bss_info->rssi * 100;
-#if defined(WLP2P) && (ENABLE_P2P_INTERFACE)
- if (wl->p2p_net && wl->scan_request &&
- wl->scan_request->dev == wl->p2p_net) {
-#else
- if (p2p_is_on(wl) && p2p_scan(wl)) {
-#endif
- /* find the P2PIE, if we do not find it, we will discard this frame */
- wifi_p2p_ie_t *p2p_ie;
- if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)beacon_proberesp->variable,
- wl_get_ielen(wl))) == NULL) {
- WL_ERR(("Couldn't find P2PIE in probe response/beacon\n"));
- kfree(notif_bss_info);
- return err;
- }
- }
cbss = cfg80211_inform_bss_frame(wiphy, channel, mgmt,
le16_to_cpu(notif_bss_info->frame_len), signal, GFP_KERNEL);
@@ -5771,8 +5820,9 @@ wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev,
}
if (len)
memcpy(body, data, len);
+
wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
- NULL, 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bsscfgidx, &wl->ioctl_buf_sync);
+ NULL, 0, wl->ioctl_buf, WLC_IOCTL_SMLEN, bsscfgidx, &wl->ioctl_buf_sync);
memcpy(da.octet, wl->ioctl_buf, ETHER_ADDR_LEN);
err = wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
switch (event) {
@@ -5920,7 +5970,8 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
if (wl_get_drv_status(wl, CONNECTED, ndev)) {
scb_val_t scbval;
u8 *curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
- printk("link down, call cfg80211_disconnected\n");
+ printk("link down, call cfg80211_disconnected. (reason=%d)\n",
+ ntoh32(e->reason));
WL_DBG(("con=%02x:%02x:%02x:%02x:%02x:%02x\n",
curbssid[0], curbssid[1], curbssid[2],
curbssid[3],curbssid[4], curbssid[5]));
@@ -6127,7 +6178,7 @@ static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
}
}
-static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev)
+static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev, u8 is_roam_done)
{
struct cfg80211_bss *bss;
struct wl_bss_info *bi;
@@ -6167,7 +6218,7 @@ static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev)
err = -EIO;
goto update_bss_info_out;
}
- err = wl_inform_single_bss(wl, bi);
+ err = wl_inform_single_bss(wl, bi, is_roam_done);
if (unlikely(err))
goto update_bss_info_out;
@@ -6218,7 +6269,7 @@ wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
wl_get_assoc_ies(wl, ndev);
wl_update_prof(wl, ndev, NULL, (void *)(e->addr.octet), WL_PROF_BSSID);
curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
- wl_update_bss_info(wl, ndev);
+ wl_update_bss_info(wl, ndev, 1);
wl_update_pmklist(ndev, wl->pmk_list, err);
cfg80211_roamed(ndev,
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
@@ -6239,6 +6290,7 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
const wl_event_msg_t *e, void *data, bool completed)
{
struct wl_connect_info *conn_info = wl_to_conn(wl);
+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
s32 err = 0;
u8 *curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
@@ -6279,9 +6331,11 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
}
wl_update_prof(wl, ndev, NULL, (void *)(e->addr.octet), WL_PROF_BSSID);
curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
- wl_update_bss_info(wl, ndev);
+ wl_update_bss_info(wl, ndev, 0);
wl_update_pmklist(ndev, wl->pmk_list, err);
wl_set_drv_status(wl, CONNECTED, ndev);
+ if (dhd->roam_env_detection)
+ wldev_iovar_setint(ndev, "roam_env_detection", AP_ENV_INDETERMINATE);
}
cfg80211_connect_result(ndev,
curbssid,
@@ -6498,7 +6552,7 @@ wl_notify_rx_mgmt_frame(struct wl_priv *wl, struct net_device *ndev,
#endif
if (event == WLC_E_ACTION_FRAME_RX) {
wldev_iovar_getbuf_bsscfg(dev, "cur_etheraddr",
- NULL, 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bsscfgidx, &wl->ioctl_buf_sync);
+ NULL, 0, wl->ioctl_buf, WLC_IOCTL_SMLEN, bsscfgidx, &wl->ioctl_buf_sync);
err = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
if( err < 0) {
@@ -7211,6 +7265,7 @@ static s32 wl_escan_handler(struct wl_priv *wl,
wl_escan_result_t *escan_result;
wl_bss_info_t *bss = NULL;
wl_scan_results_t *list;
+ wifi_p2p_ie_t * p2p_ie;
u32 bi_length;
u32 i;
u8 *p2p_dev_addr = NULL;
@@ -7288,6 +7343,21 @@ static s32 wl_escan_handler(struct wl_priv *wl,
} else {
int cur_len = 0;
list = (wl_scan_results_t *)wl->escan_info.escan_buf[wl->escan_info.cur_sync_id%2];
+#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF)
+ if (wl->p2p_net && wl->scan_request &&
+ wl->scan_request->dev == wl->p2p_net) {
+#else
+ if (p2p_is_on(wl) && p2p_scan(wl)) {
+#endif
+ /* p2p scan && allow only probe response */
+ if (bi->flags & WL_BSS_FLAGS_FROM_BEACON)
+ goto exit;
+ if ((p2p_ie = wl_cfgp2p_find_p2pie(((u8 *) bi) + bi->ie_offset,
+ bi->ie_length)) == NULL) {
+ WL_ERR(("Couldn't find P2PIE in probe response/beacon\n"));
+ goto exit;
+ }
+ }
#define WLC_BSS_RSSI_ON_CHANNEL 0x0002
for (i = 0; i < list->count; i++) {
bss = bss ? (wl_bss_info_t *)((uintptr)bss + dtoh32(bss->length))
@@ -7296,41 +7366,73 @@ static s32 wl_escan_handler(struct wl_priv *wl,
CHSPEC_BAND(bi->chanspec) == CHSPEC_BAND(bss->chanspec) &&
bi->SSID_len == bss->SSID_len &&
!bcmp(bi->SSID, bss->SSID, bi->SSID_len)) {
- if (bss->dtoh32(ie_length) != bi_length) {
- int prev_len = dtoh32(bss->length);
- WL_SCAN2(("bss info replacement is occured(bcast:%d->probresp%d)\n",
- bss->ie_length, bi->ie_length));
- /* prev : broadcast, cur : prob_resp */
- if (list->count != 1 && i < list->count -1) {
- /* memory copy required by this case only */
- memcpy((u8 *)bss,
- (u8 *)bss + prev_len, list->buflen - cur_len - prev_len);
- }
- list->buflen -= prev_len;
- if (bi_length > ESCAN_BUF_SIZE - list->buflen) {
- WL_ERR(("Buffer is too small: ignoring\n"));
- goto exit;
- }
- memcpy(&(((u8 *)list)[list->buflen]), bi, bi_length);
- list->version = dtoh32(bi->version);
- list->buflen += bi_length;
+
+ /* do not allow beacon data to update
+ *the data recd from a probe response
+ */
+ if (!(bss->flags & WL_BSS_FLAGS_FROM_BEACON) &&
+ (bi->flags & WL_BSS_FLAGS_FROM_BEACON))
goto exit;
- }
- if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
- (bi->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
+
+ WL_DBG(("%s("MACSTR"), i=%d prev: RSSI %d"
+ " flags 0x%x, new: RSSI %d flags 0x%x\n",
+ bss->SSID, MAC2STR(bi->BSSID.octet), i,
+ bss->RSSI, bss->flags, bi->RSSI, bi->flags));
+
+ if ((bss->flags & WL_BSS_FLAGS_RSSI_ONCHANNEL) ==
+ (bi->flags & WL_BSS_FLAGS_RSSI_ONCHANNEL)) {
/* preserve max RSSI if the measurements are
* both on-channel or both off-channel
*/
- bss->RSSI = MAX(bss->RSSI, bi->RSSI);
- } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
- (bi->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
+ WL_SCAN(("%s("MACSTR"), same onchan"
+ ", RSSI: prev %d new %d\n",
+ bss->SSID, MAC2STR(bi->BSSID.octet),
+ bss->RSSI, bi->RSSI));
+ bi->RSSI = MAX(bss->RSSI, bi->RSSI);
+ } else if ((bss->flags & WL_BSS_FLAGS_RSSI_ONCHANNEL) &&
+ (bi->flags & WL_BSS_FLAGS_RSSI_ONCHANNEL) == 0) {
/* preserve the on-channel rssi measurement
* if the new measurement is off channel
*/
- bss->RSSI = bi->RSSI;
- bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
+ WL_SCAN(("%s("MACSTR"), prev onchan"
+ ", RSSI: prev %d new %d\n",
+ bss->SSID, MAC2STR(bi->BSSID.octet),
+ bss->RSSI, bi->RSSI));
+ bi->RSSI = bss->RSSI;
+ bi->flags |= WL_BSS_FLAGS_RSSI_ONCHANNEL;
}
+ if (dtoh32(bss->length) != bi_length) {
+ u32 prev_len = dtoh32(bss->length);
+ WL_SCAN(("bss info replacement"
+ " is occured(bcast:%d->probresp%d)\n",
+ bss->ie_length, bi->ie_length));
+ WL_DBG(("%s("MACSTR"), replacement!(%d -> %d)\n",
+ bss->SSID, MAC2STR(bi->BSSID.octet),
+ prev_len, bi_length));
+
+ if (list->buflen - prev_len + bi_length
+ > ESCAN_BUF_SIZE) {
+ WL_ERR(("Buffer is too small: keep the"
+ " previous result of this AP\n"));
+ /* Only update RSSI */
+ bss->RSSI = bi->RSSI;
+ bss->flags |= (bi->flags
+ & WL_BSS_FLAGS_RSSI_ONCHANNEL);
+ goto exit;
+ }
+
+ if (i < list->count - 1) {
+ /* memory copy required by this case only */
+ memmove((u8 *)bss + bi_length,
+ (u8 *)bss + prev_len,
+ list->buflen - cur_len - prev_len);
+ }
+ list->buflen -= prev_len;
+ list->buflen += bi_length;
+ }
+ list->version = dtoh32(bi->version);
+ memcpy((u8 *)bss, (u8 *)bi, bi_length);
goto exit;
}
cur_len += dtoh32(bss->length);
@@ -7435,7 +7537,6 @@ static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_in
{
s32 pm = PM_FAST;
s32 err = BCME_OK;
- s32 glom = -1;
u32 chan = 0;
u32 chanspec = 0;
u32 prev_chan = 0;
@@ -7493,12 +7594,7 @@ static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_in
if ((wl_get_mode_by_netdev(wl, _net_info->ndev) == WL_MODE_AP) && p2p_is_on(wl))
if (wl_add_remove_eventmsg(primary_dev, WLC_E_P2P_PROBREQ_MSG, true) != BCME_OK)
CFGP2P_ERR((" failed to set WLC_E_P2P_PROPREQ_MSG\n"));
- if (!wl->vsdb_mode && (connected_cnt > 1)) {
- if (wldev_iovar_getint(primary_dev, "bus:txglom", (s32 *)&glom) == BCME_OK) {
- wl->glom = glom;
- wldev_iovar_setint(primary_dev, "bus:txglom", 0);
- }
- }
+
break;
}
default:
@@ -7531,9 +7627,6 @@ static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_in
}
}
}
- if (wl->glom != -1)
- wldev_iovar_setint(primary_dev, "bus:txglom", wl->glom);
- wl->glom = -1;
}
if ((wl_get_mode_by_netdev(wl, _net_info->ndev) == WL_MODE_AP) && p2p_is_on(wl))
if (wl_add_remove_eventmsg(primary_dev, WLC_E_P2P_PROBREQ_MSG, false) != BCME_OK)
@@ -7596,7 +7689,8 @@ static s32 wl_init_priv(struct wl_priv *wl)
wl->rf_blocked = false;
wl->first_remain = true;
wl->wlfc_on = false;
- wl->glom = -1;
+
+ /* register interested state */
set_bit(WL_STATUS_CONNECTED, &wl->interrested_state);
spin_lock_init(&wl->cfgdrv_lock);
mutex_init(&wl->ioctl_buf_sync);
@@ -8231,6 +8325,7 @@ s32 wl_update_wiphybands(struct wl_priv *wl)
s32 index = 0;
s32 nmode = 0;
s32 bw_cap = 0;
+ s32 cur_band = -1;
if (wl == NULL)
wl = wlcfg_drv_priv;
dev = wl_to_prmry_ndev(wl);
@@ -8243,6 +8338,13 @@ s32 wl_update_wiphybands(struct wl_priv *wl)
WL_ERR(("error (%d)\n", err));
return err;
}
+ err = wldev_ioctl(dev, WLC_GET_BAND, &cur_band,
+ sizeof(s32), false);
+ if (unlikely(err)) {
+ WL_ERR(("error (%d)\n", err));
+ return err;
+ }
+
err = wldev_iovar_getint(dev, "nmode", &nmode);
if (err) {
return err;
@@ -8258,6 +8360,11 @@ s32 wl_update_wiphybands(struct wl_priv *wl)
WL_ERR(("wl_construct_reginfo() fails err=%d\n", err));
return err;
}
+ if ((cur_band == WLC_BAND_2G) ||
+ (cur_band == WLC_BAND_5G)) {
+ bandlist[0] = 1;
+ bandlist[1] = cur_band;
+ }
wiphy = wl_to_wiphy(wl);
nband = bandlist[0];
@@ -8706,8 +8813,8 @@ s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len,
wl_cfgp2p_generate_bss_mac(&primary_mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
/* In case of p2p_listen command, supplicant send remain_on_channel
- * without turning on P2P
- */
+ * without turning on P2P
+ */
p2p_on(wl) = true;
ret = wl_cfgp2p_enable_discovery(wl, net, NULL, 0);
@@ -8817,7 +8924,7 @@ static void wl_cfg80211_clear_parent_dev(void)
static void get_primary_mac(struct wl_priv *wl, struct ether_addr *mac)
{
wldev_iovar_getbuf_bsscfg(wl_to_prmry_ndev(wl), "cur_etheraddr", NULL,
- 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &wl->ioctl_buf_sync);
+ 0, wl->ioctl_buf, WLC_IOCTL_SMLEN, 0, &wl->ioctl_buf_sync);
memcpy(mac->octet, wl->ioctl_buf, ETHER_ADDR_LEN);
}
int wl_cfg80211_do_driver_init(struct net_device *net)
diff --git a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.h
index 04bd49e..4c9e516 100644
--- a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.h
+++ b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.h
@@ -455,7 +455,6 @@ struct wl_priv {
void *pub;
u32 iface_cnt;
u32 channel; /* current channel */
- s32 glom;
#ifdef WL_CFG80211_SYNC_GON_TIME
u32 af_sent_channel; /* channel action frame is sent */
/* save the next gon af subtype when it needs to wait more time for next gon af
diff --git a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.c b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.c
index fdc2ed8..9071637 100644
--- a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.c
+++ b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.c
@@ -1137,8 +1137,7 @@ wl_cfgp2p_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len, const u8 *oui, u32 oui_len, u
/* If the contents match the SAMSUNG OUI */
if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
- !bcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
- !bcmp(oui, SAMSUNG_OUI, SAMSUNG_OUI_LEN)) {
+ !bcmp(&ie[TLV_BODY_OFF], oui, oui_len)) {
return TRUE;
}
@@ -1318,7 +1317,7 @@ s32 wl_cfgp2p_p2p_listen_suspend(void)
if ((ret = wl_add_remove_eventmsg(netdev, WLC_E_P2P_PROBREQ_MSG, enable)) != BCME_OK) {
CFGP2P_ERR((" failed to %s WLC_E_P2P_PROPREQ_MSG\n", enable? "set":"unset" ));
}
-
+
}
exit:
return ret;
@@ -1369,8 +1368,10 @@ wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev,
#ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
wl_clr_drv_status(wl, FAKE_REMAINING_ON_CHANNEL, ndev);
#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
- cfg80211_remain_on_channel_expired(ndev, wl->last_roc_id,
- &wl->remain_on_chan, wl->remain_on_chan_type, GFP_KERNEL);
+ if (ndev && (ndev->ieee80211_ptr != NULL)) {
+ cfg80211_remain_on_channel_expired(ndev, wl->last_roc_id,
+ &wl->remain_on_chan, wl->remain_on_chan_type, GFP_KERNEL);
+ }
}
if (wl_add_remove_eventmsg(netdev, WLC_E_P2P_PROBREQ_MSG, false) != BCME_OK) {
CFGP2P_ERR((" failed to unset WLC_E_P2P_PROPREQ_MSG\n"));
@@ -1442,7 +1443,7 @@ wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms)
/* Clear WLC_E_P2P_PROBREQ_MSG in case of early suspend and p2p ie != 0 */
enable = false;
}
-
+
if (wl_add_remove_eventmsg(netdev, WLC_E_P2P_PROBREQ_MSG, enable) != BCME_OK) {
CFGP2P_ERR((" failed to set WLC_E_P2P_PROPREQ_MSG\n"));
}
@@ -1730,7 +1731,7 @@ wl_cfgp2p_supported(struct wl_priv *wl, struct net_device *ndev)
ret = wldev_iovar_getint(ndev, "p2p",
&p2p_supported);
if (ret < 0) {
- CFGP2P_ERR(("wl p2p error %d\n", ret));
+ CFGP2P_ERR(("wl p2p supported IOVAR = %d\n", ret));
return 0;
}
if (p2p_supported == 1) {
diff --git a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_iw.c b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_iw.c
index 9824555..c25f173 100644
--- a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_iw.c
+++ b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_iw.c
@@ -1416,6 +1416,7 @@ wl_iw_get_scan(
struct iw_event iwe;
wl_bss_info_t *bi = NULL;
int error, i, j;
+ int rssi = 0;
char *event = extra, *end = extra + dwrq->length, *value;
uint buflen = dwrq->length;
@@ -1482,10 +1483,13 @@ wl_iw_get_scan(
iwe.u.freq.e = 6;
event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN);
-
iwe.cmd = IWEVQUAL;
- iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI));
- iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI);
+ rssi = dtoh16(bi->RSSI);
+ if (rssi >= WL_IW_RSSI_INVALID)
+ rssi = WL_IW_RSSI_MAXVAL;
+
+ 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);
@@ -1607,8 +1611,12 @@ wl_iw_iscan_get_scan(
iwe.cmd = IWEVQUAL;
- iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI));
- iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI);
+ rssi = dtoh16(bi->RSSI);
+ if (rssi >= WL_IW_RSSI_INVALID)
+ rssi = WL_IW_RSSI_MAXVAL;
+
+ 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);
@@ -3405,6 +3413,9 @@ int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstat
goto done;
rssi = dtoh32(scb_val.val);
+ if (rssi >= WL_IW_RSSI_INVALID)
+ rssi = WL_IW_RSSI_MAXVAL;
+
WL_TRACE(("wl_iw_get_wireless_stats rssi=%d ****** \n", rssi));
if (rssi <= WL_IW_RSSI_NO_SIGNAL)
wstats->qual.qual = 0;
diff --git a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_iw.h b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_iw.h
index b38f20f..3929e6c 100644
--- a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_iw.h
+++ b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_iw.h
@@ -77,6 +77,7 @@ struct cntry_locales_custom {
#define WL_IW_RSSI_VERY_GOOD -58
#define WL_IW_RSSI_EXCELLENT -57
#define WL_IW_RSSI_INVALID 0
+#define WL_IW_RSSI_MAXVAL -15
#define MAX_WX_STRING 80
#define SSID_FMT_BUF_LEN ((4 * 32) + 1)
#define isprint(c) bcm_isprint(c)
diff --git a/drivers/net/wireless/bcmdhd/src/wl/sys/wldev_common.c b/drivers/net/wireless/bcmdhd/src/wl/sys/wldev_common.c
index b4ecf11..516da89 100644
--- a/drivers/net/wireless/bcmdhd/src/wl/sys/wldev_common.c
+++ b/drivers/net/wireless/bcmdhd/src/wl/sys/wldev_common.c
@@ -31,6 +31,7 @@
#include <wldev_common.h>
#include <bcmutils.h>
+#include <wl_iw.h>
#define htod32(i) i
#define htod16(i) i
@@ -41,13 +42,13 @@
#define WLDEV_ERROR(args) \
do { \
- printk(KERN_ERR "WLDEV-ERROR) %s : ", __func__); \
+ printk(KERN_ERR "WLDEV-INFO2) %s : ", __func__); \
printk args; \
} while (0)
#define WLDEV_INFO(args) \
do { \
- printk(KERN_INFO "WLDEV-ERROR) %s : ", __func__); \
+ printk(KERN_INFO "WLDEV-INFO) %s : ", __func__); \
printk args; \
} while (0)
@@ -300,6 +301,10 @@ int wldev_get_rssi(
return error;
*prssi = dtoh32(scb_val.val);
+ /* when the return value is zero. skip overrinding code */
+ if (*prssi > WL_IW_RSSI_INVALID)
+ *prssi = WL_IW_RSSI_MAXVAL;
+
return error;
}
diff --git a/drivers/video/samsung/s5p-dsim.c b/drivers/video/samsung/s5p-dsim.c
index 4f2cb7f..d128618 100644
--- a/drivers/video/samsung/s5p-dsim.c
+++ b/drivers/video/samsung/s5p-dsim.c
@@ -143,8 +143,13 @@ void set_dsim_hs_clk_toggle_count(u8 count)
struct dsim_global *dsim = g_dsim;
dsim->dsim_toggle_per_frame_count = count;
- if (dsim->dsim_lcd_info->lcd_enabled)
- s5p_dsim_frame_done_interrupt_enable(dsim, count ? 1 : 0);
+ if (dsim->dsim_lcd_info->lcd_enabled) {
+ if (dsim->dsim_info->hs_toggle) {
+ s5p_dsim_frame_done_interrupt_enable(dsim, 1);
+ schedule_delayed_work(&dsim->check_hs_toggle_work, msecs_to_jiffies(60000));
+ } else
+ s5p_dsim_frame_done_interrupt_enable(dsim, count ? 1 : 0);
+ }
}
static void dsim_work_q_handler(struct work_struct *work)
@@ -162,7 +167,7 @@ static void dsim_check_hs_toggle_work_q_handler(struct work_struct *work)
if (dsim->dsim_info->hs_toggle) {
dev_info(dsim->dev, "check_hs_toggle\n");
- schedule_delayed_work(&dsim->check_hs_toggle_work, msecs_to_jiffies(120000));
+ schedule_delayed_work(&dsim->check_hs_toggle_work, msecs_to_jiffies(60000));
}
}
@@ -439,7 +444,7 @@ static irqreturn_t s5p_dsim_isr(int irq, void *dev_id)
s5p_dsim_toggle_hs_clock(dsim->reg_base);
if (!dsim->dsim_toggle_per_frame_count) {
s5p_dsim_frame_done_interrupt_enable(dsim, 0);
- if (likely(dsim->dsim_info->hs_toggle - 1))
+ if (likely(dsim->dsim_info->hs_toggle))
schedule_delayed_work(&dsim->dsim_work, dsim->dsim_info->hs_toggle);
}
if (dsim->dsim_toggle_per_frame_count)
@@ -1219,15 +1224,10 @@ static int hs_toggle_store(struct device *dev,
else {
dev_info(dev, "%s - %d, %d\n", __func__, jiffies_to_msecs(dsim->dsim_info->hs_toggle), value);
- if (value == 1) {
+ if (value == 1)
dsim->dsim_info->hs_toggle = msecs_to_jiffies(3000);
- s5p_dsim_frame_done_interrupt_enable(dsim, 1);
- schedule_delayed_work(&dsim->check_hs_toggle_work, msecs_to_jiffies(120000));
- } else {
+ else
dsim->dsim_info->hs_toggle = 0;
- s5p_dsim_frame_done_interrupt_enable(dsim, 0);
- cancel_delayed_work(&dsim->check_hs_toggle_work);
- }
}
return size;
}