aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2012-04-02 16:13:13 -0700
committerDmitry Shmidt <dimitrysh@google.com>2012-04-02 16:13:13 -0700
commit5c9338ba7a8b7d00f9baa5dabf6c9061bba76571 (patch)
treedb2e78aeb4ffa5fcb5359a2f061f8e1e7fd7e575
parenta1d5de52cb468158a052a706cbdaecda86b74087 (diff)
parent1dd49da642eb92855fe41a30f8e1e50e70dbac8e (diff)
downloadkernel_samsung_tuna-5c9338ba7a8b7d00f9baa5dabf6c9061bba76571.zip
kernel_samsung_tuna-5c9338ba7a8b7d00f9baa5dabf6c9061bba76571.tar.gz
kernel_samsung_tuna-5c9338ba7a8b7d00f9baa5dabf6c9061bba76571.tar.bz2
Merge branch 'android-3.0' into android-omap-3.0
-rw-r--r--drivers/net/wireless/bcmdhd/dhd.h2
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_common.c13
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_dbg.h4
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_linux.c44
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_proto.h2
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_sdio.c19
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.c10
7 files changed, 62 insertions, 32 deletions
diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h
index 47ffec53..c7223e6 100644
--- a/drivers/net/wireless/bcmdhd/dhd.h
+++ b/drivers/net/wireless/bcmdhd/dhd.h
@@ -508,7 +508,7 @@ extern uint dhd_bus_status(dhd_pub_t *dhdp);
extern int dhd_bus_start(dhd_pub_t *dhdp);
extern int dhd_bus_membytes(dhd_pub_t *dhdp, bool set, uint32 address, uint8 *data, uint size);
extern void dhd_print_buf(void *pbuf, int len, int bytes_per_line);
-extern bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf);
+extern bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf, int *retval);
extern uint dhd_bus_chip_id(dhd_pub_t *dhdp);
#if defined(KEEP_ALIVE)
diff --git a/drivers/net/wireless/bcmdhd/dhd_common.c b/drivers/net/wireless/bcmdhd/dhd_common.c
index 4fa07fb..ca5a76e 100644
--- a/drivers/net/wireless/bcmdhd/dhd_common.c
+++ b/drivers/net/wireless/bcmdhd/dhd_common.c
@@ -300,7 +300,7 @@ dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifindex, wl_ioctl_t *ioc, void *buf, int le
dhd_os_proto_block(dhd_pub);
ret = dhd_prot_ioctl(dhd_pub, ifindex, ioc, buf, len);
- if (!ret)
+ if (ret)
dhd_os_check_hang(dhd_pub, ifindex, ret);
dhd_os_proto_unblock(dhd_pub);
@@ -1724,10 +1724,10 @@ fail:
/*
* returns = TRUE if associated, FALSE if not associated
*/
-bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf)
+bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf, int *retval)
{
char bssid[6], zbuf[6];
- int ret = -1;
+ int ret;
bzero(bssid, 6);
bzero(zbuf, 6);
@@ -1735,6 +1735,9 @@ bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf)
ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_BSSID, (char *)&bssid, ETHER_ADDR_LEN, FALSE, 0);
DHD_TRACE((" %s WLC_GET_BSSID ioctl res = %d\n", __FUNCTION__, ret));
+ if (retval)
+ *retval = ret;
+
if (ret == BCME_NOTASSOCIATED) {
DHD_TRACE(("%s: not associated! res:%d\n", __FUNCTION__, ret));
}
@@ -1771,7 +1774,7 @@ dhd_get_dtim_skip(dhd_pub_t *dhd)
bcn_li_dtim = dhd->dtim_skip;
/* Check if associated */
- if (dhd_is_associated(dhd, NULL) == FALSE) {
+ if (dhd_is_associated(dhd, NULL, NULL) == FALSE) {
DHD_TRACE(("%s NOT assoc ret %d\n", __FUNCTION__, ret));
goto exit;
}
@@ -1884,7 +1887,7 @@ dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled)
memset(iovbuf, 0, sizeof(iovbuf));
#ifndef WL_SCHED_SCAN
- if ((pfn_enabled) && (dhd_is_associated(dhd, NULL) == TRUE)) {
+ if ((pfn_enabled) && (dhd_is_associated(dhd, NULL, NULL) == TRUE)) {
DHD_ERROR(("%s pno is NOT enable : called in assoc mode , ignore\n", __FUNCTION__));
return ret;
}
diff --git a/drivers/net/wireless/bcmdhd/dhd_dbg.h b/drivers/net/wireless/bcmdhd/dhd_dbg.h
index a195cbe..01be6a1 100644
--- a/drivers/net/wireless/bcmdhd/dhd_dbg.h
+++ b/drivers/net/wireless/bcmdhd/dhd_dbg.h
@@ -29,8 +29,8 @@
#if defined(DHD_DEBUG)
-#define DHD_ERROR(args) do {if ((dhd_msg_level & DHD_ERROR_VAL) && (net_ratelimit())) \
- printf args;} while (0)
+#define DHD_ERROR(args) do {if ((dhd_msg_level & DHD_ERROR_VAL) && (net_ratelimit())) \
+ printf args;} while (0)
#define DHD_TRACE(args) do {if (dhd_msg_level & DHD_TRACE_VAL) printf args;} while (0)
#define DHD_INFO(args) do {if (dhd_msg_level & DHD_INFO_VAL) printf args;} while (0)
#define DHD_DATA(args) do {if (dhd_msg_level & DHD_DATA_VAL) printf args;} while (0)
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index 0205e7c..1e28fb8 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -129,6 +129,9 @@ DECLARE_WAIT_QUEUE_HEAD(dhd_dpc_wait);
#if defined(OOB_INTR_ONLY)
extern void dhd_enable_oob_intr(struct dhd_bus *bus, bool enable);
#endif /* defined(OOB_INTR_ONLY) */
+
+static void dhd_hang_process(struct work_struct *work);
+
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
MODULE_LICENSE("GPL v2");
#endif /* LinuxVer */
@@ -247,6 +250,7 @@ typedef struct dhd_info {
bool dhd_tasklet_create;
#endif /* DHDTHREAD */
tsk_ctl_t thr_sysioc_ctl;
+ struct work_struct work_hang;
/* Wakelocks */
#if defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
@@ -2750,6 +2754,8 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
}
dhd_state |= DHD_ATTACH_STATE_THREADS_CREATED;
+ INIT_WORK(&dhd->work_hang, dhd_hang_process);
+
/*
* Save the dhd_info into the priv
*/
@@ -3632,6 +3638,8 @@ void dhd_detach(dhd_pub_t *dhdp)
}
#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */
+ cancel_work_sync(&dhd->work_hang);
+
#if defined(WL_WIRELESS_EXT)
if (dhd->dhd_state & DHD_ATTACH_STATE_WL_ATTACH) {
/* Detatch and unlink in the iw */
@@ -4443,29 +4451,37 @@ dhd_dev_get_pno_status(struct net_device *dev)
#endif /* PNO_SUPPORT */
+static void dhd_hang_process(struct work_struct *work)
+{
+ dhd_info_t *dhd;
+ struct net_device *dev;
+
+ dhd = (dhd_info_t *)container_of(work, dhd_info_t, work_hang);
+ dev = dhd->iflist[0]->net;
+
+ if (dev) {
+ rtnl_lock();
+ dev_close(dev);
+ rtnl_unlock();
+#if defined(WL_WIRELESS_EXT)
+ wl_iw_send_priv_event(dev, "HANG");
+#endif
+#if defined(WL_CFG80211)
+ wl_cfg80211_hang(dev, WLAN_REASON_UNSPECIFIED);
+#endif
+ }
+}
+
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
int net_os_send_hang_message(struct net_device *dev)
{
dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
int ret = 0;
- int need_unlock = 0;
if (dhd) {
if (!dhd->pub.hang_was_sent) {
dhd->pub.hang_was_sent = 1;
- if (!rtnl_is_locked()) {
- need_unlock = 1;
- rtnl_lock();
- }
- dev_close(dev);
- if (need_unlock)
- rtnl_unlock();
-#if defined(WL_WIRELESS_EXT)
- ret = wl_iw_send_priv_event(dev, "HANG");
-#endif
-#if defined(WL_CFG80211)
- ret = wl_cfg80211_hang(dev, WLAN_REASON_UNSPECIFIED);
-#endif
+ schedule_work(&dhd->work_hang);
}
}
return ret;
diff --git a/drivers/net/wireless/bcmdhd/dhd_proto.h b/drivers/net/wireless/bcmdhd/dhd_proto.h
index e0a54ad..bb1d736 100644
--- a/drivers/net/wireless/bcmdhd/dhd_proto.h
+++ b/drivers/net/wireless/bcmdhd/dhd_proto.h
@@ -34,7 +34,7 @@
#include <wlioctl.h>
#ifndef IOCTL_RESP_TIMEOUT
-#define IOCTL_RESP_TIMEOUT 20000 /* In milli second */
+#define IOCTL_RESP_TIMEOUT 2000 /* In milli second */
#endif
/*
diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c
index 8461d88..3371db8 100644
--- a/drivers/net/wireless/bcmdhd/dhd_sdio.c
+++ b/drivers/net/wireless/bcmdhd/dhd_sdio.c
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: dhd_sdio.c 315747 2012-02-18 00:16:06Z $
+ * $Id: dhd_sdio.c 324417 2012-03-29 03:15:15Z $
*/
#include <typedefs.h>
@@ -754,7 +754,8 @@ dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok)
uint oldstate = bus->clkstate;
#endif /* DHD_DEBUG */
- DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+ DHD_TRACE(("%s: Enter bus->clkstate %u target %u\n", __FUNCTION__,
+ bus->clkstate, target));
/* Early exit if we're already there */
if (bus->clkstate == target) {
@@ -1454,7 +1455,7 @@ dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen)
{
int timeleft;
uint rxlen = 0;
- bool pending;
+ bool pending = FALSE;
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
@@ -4597,6 +4598,15 @@ clkwait:
if (TXCTLOK(bus) && bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL)) {
int ret, i;
+ uint8* frame_seq = bus->ctrl_frame_buf + SDPCM_FRAMETAG_LEN;
+
+ if (((bus->sih->chip == BCM4329_CHIP_ID) || /* limit to 4329 & 4330 for now */
+ (bus->sih->chip == BCM4330_CHIP_ID)) && (*frame_seq != bus->tx_seq)) {
+ DHD_ERROR(("%s IOCTL frame seq lag detected!"
+ " frm_seq:%d != bus->tx_seq:%d, corrected\n",
+ __FUNCTION__, *frame_seq, bus->tx_seq));
+ *frame_seq = bus->tx_seq;
+ }
ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC,
(uint8 *)bus->ctrl_frame_buf, (uint32)bus->ctrl_frame_len,
@@ -6289,11 +6299,12 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag)
return bcmerror;
}
+/* Get Chip ID version */
uint dhd_bus_chip_id(dhd_pub_t *dhdp)
{
dhd_bus_t *bus = dhdp->bus;
- return bus->sih->chip;
+ return bus->sih->chip;
}
int
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index e1c62c6..2c322f4 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -2844,11 +2844,11 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
#endif
} else if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_BSS) {
u8 *curmacp = wl_read_prof(wl, dev, WL_PROF_BSSID);
+ err = -ENODEV;
if (!wl_get_drv_status(wl, CONNECTED, dev) ||
- (dhd_is_associated(dhd, NULL) == FALSE)) {
+ (dhd_is_associated(dhd, NULL, &err) == FALSE)) {
- WL_ERR(("NOT assoc\n"));
- err = -ENODEV;
+ WL_ERR(("NOT assoc: %d\n", err));
goto get_station_err;
}
if (memcmp(mac, curmacp, ETHER_ADDR_LEN)) {
@@ -2881,9 +2881,9 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
WL_DBG(("RSSI %d dBm\n", rssi));
get_station_err:
- if (err) {
+ if (err && (err != -ETIMEDOUT) && (err != -EIO)) {
/* Disconnect due to zero BSSID or error to get RSSI */
- WL_ERR(("force cfg80211_disconnected\n"));
+ WL_ERR(("force cfg80211_disconnected: %d\n", err));
wl_clr_drv_status(wl, CONNECTED, dev);
cfg80211_disconnected(dev, 0, NULL, 0, GFP_KERNEL);
wl_link_down(wl);