aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKalimochoAz <calimochoazucarado@gmail.com>2012-10-31 22:54:36 +0100
committerKalimochoAz <calimochoazucarado@gmail.com>2012-10-31 22:54:36 +0100
commitda177410c083645a5fc884e5cd8040a519b06c4e (patch)
treedc2c78f2cf1e7ceeb5c3218772644bd040aec559
parentcb65a3eb390b7cc995c4aa6b7bff32a4696242e6 (diff)
parent834029ac9d0ad8dea4e6a21bc34877dc3740b9f4 (diff)
downloadkernel_samsung_crespo-da177410c083645a5fc884e5cd8040a519b06c4e.zip
kernel_samsung_crespo-da177410c083645a5fc884e5cd8040a519b06c4e.tar.gz
kernel_samsung_crespo-da177410c083645a5fc884e5cd8040a519b06c4e.tar.bz2
Merge branch android android-3.0 into HEAD
-rw-r--r--drivers/net/wireless/bcmdhd/dhd.h8
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_linux.c64
-rw-r--r--drivers/net/wireless/bcmdhd/include/bcmutils.h2
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.c30
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.h2
5 files changed, 94 insertions, 12 deletions
diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h
index 34616d3..5160ee1 100644
--- a/drivers/net/wireless/bcmdhd/dhd.h
+++ b/drivers/net/wireless/bcmdhd/dhd.h
@@ -301,6 +301,8 @@ extern int dhd_os_wake_unlock(dhd_pub_t *pub);
extern int dhd_os_wake_lock_timeout(dhd_pub_t *pub);
extern int dhd_os_wake_lock_rx_timeout_enable(dhd_pub_t *pub, int val);
extern int dhd_os_wake_lock_ctrl_timeout_enable(dhd_pub_t *pub, int val);
+extern int dhd_os_wd_wake_lock(dhd_pub_t *pub);
+extern int dhd_os_wd_wake_unlock(dhd_pub_t *pub);
inline static void MUTEX_LOCK_SOFTAP_SET_INIT(dhd_pub_t * dhdp)
{
@@ -323,8 +325,10 @@ inline static void MUTEX_UNLOCK_SOFTAP_SET(dhd_pub_t * dhdp)
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
}
-#define DHD_OS_WAKE_LOCK(pub) dhd_os_wake_lock(pub)
-#define DHD_OS_WAKE_UNLOCK(pub) dhd_os_wake_unlock(pub)
+#define DHD_OS_WAKE_LOCK(pub) dhd_os_wake_lock(pub)
+#define DHD_OS_WAKE_UNLOCK(pub) dhd_os_wake_unlock(pub)
+#define DHD_OS_WD_WAKE_LOCK(pub) dhd_os_wd_wake_lock(pub)
+#define DHD_OS_WD_WAKE_UNLOCK(pub) dhd_os_wd_wake_unlock(pub)
#define DHD_OS_WAKE_LOCK_TIMEOUT(pub) dhd_os_wake_lock_timeout(pub)
#define DHD_OS_WAKE_LOCK_RX_TIMEOUT_ENABLE(pub, val) dhd_os_wake_lock_rx_timeout_enable(pub, val)
#define DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(pub, val) dhd_os_wake_lock_ctrl_timeout_enable(pub, val)
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index 0f419a5..d0b4c1c 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -259,6 +259,7 @@ typedef struct dhd_info {
struct wake_lock wl_wifi; /* Wifi wakelock */
struct wake_lock wl_rxwake; /* Wifi rx wakelock */
struct wake_lock wl_ctrlwake; /* Wifi ctrl wakelock */
+ struct wake_lock wl_wdwake; /* Wifi wd wakelock */
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
@@ -270,6 +271,7 @@ typedef struct dhd_info {
#endif
spinlock_t wakelock_spinlock;
int wakelock_counter;
+ int wakelock_wd_counter;
int wakelock_rx_timeout_enable;
int wakelock_ctrl_timeout_enable;
@@ -1697,7 +1699,6 @@ dhd_watchdog_thread(void *data)
dhd_os_spin_unlock(&dhd->pub, flags);
}
dhd_os_sdunlock(&dhd->pub);
- DHD_OS_WAKE_UNLOCK(&dhd->pub);
} else {
break;
}
@@ -1711,9 +1712,7 @@ static void dhd_watchdog(ulong data)
dhd_info_t *dhd = (dhd_info_t *)data;
unsigned long flags;
- DHD_OS_WAKE_LOCK(&dhd->pub);
if (dhd->pub.dongle_reset) {
- DHD_OS_WAKE_UNLOCK(&dhd->pub);
return;
}
@@ -1737,7 +1736,6 @@ static void dhd_watchdog(ulong data)
mod_timer(&dhd->timer, jiffies + msecs_to_jiffies(dhd_watchdog_ms));
dhd_os_spin_unlock(&dhd->pub, flags);
dhd_os_sdunlock(&dhd->pub);
- DHD_OS_WAKE_UNLOCK(&dhd->pub);
}
#ifdef DHDTHREAD
@@ -2681,12 +2679,14 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
/* Initialize Wakelock stuff */
spin_lock_init(&dhd->wakelock_spinlock);
dhd->wakelock_counter = 0;
+ dhd->wakelock_wd_counter = 0;
dhd->wakelock_rx_timeout_enable = 0;
dhd->wakelock_ctrl_timeout_enable = 0;
#ifdef CONFIG_HAS_WAKELOCK
wake_lock_init(&dhd->wl_wifi, WAKE_LOCK_SUSPEND, "wlan_wake");
wake_lock_init(&dhd->wl_rxwake, WAKE_LOCK_SUSPEND, "wlan_rx_wake");
wake_lock_init(&dhd->wl_ctrlwake, WAKE_LOCK_SUSPEND, "wlan_ctrl_wake");
+ wake_lock_init(&dhd->wl_wdwake, WAKE_LOCK_SUSPEND, "wlan_wd_wake");
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
mutex_init(&dhd->dhd_net_if_mutex);
@@ -2871,12 +2871,12 @@ dhd_bus_start(dhd_pub_t *dhdp)
dhd->wd_timer_valid = FALSE;
dhd_os_spin_unlock(&dhd->pub, flags);
del_timer_sync(&dhd->timer);
-
DHD_ERROR(("%s Host failed to register for OOB\n", __FUNCTION__));
#ifdef DHDTHREAD
if (dhd->threads_only)
dhd_os_sdunlock(dhdp);
#endif /* DHDTHREAD */
+ DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
return -ENODEV;
}
@@ -2895,6 +2895,7 @@ dhd_bus_start(dhd_pub_t *dhdp)
if (dhd->threads_only)
dhd_os_sdunlock(dhdp);
#endif /* DHDTHREAD */
+ DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
return -ENODEV;
}
@@ -3787,10 +3788,15 @@ void dhd_detach(dhd_pub_t *dhdp)
if (dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT) {
#ifdef CONFIG_HAS_WAKELOCK
+ dhd->wakelock_counter = 0;
+ dhd->wakelock_wd_counter = 0;
+ dhd->wakelock_rx_timeout_enable = 0;
+ dhd->wakelock_ctrl_timeout_enable = 0;
wake_lock_destroy(&dhd->wl_wifi);
wake_lock_destroy(&dhd->wl_rxwake);
wake_lock_destroy(&dhd->wl_ctrlwake);
-#endif
+ wake_lock_destroy(&dhd->wl_wdwake);
+#endif /* CONFIG_HAS_WAKELOCK */
}
}
@@ -3983,11 +3989,18 @@ dhd_os_wd_timer(void *bus, uint wdtick)
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+ if (!dhd)
+ return;
+
+ if (wdtick)
+ DHD_OS_WD_WAKE_LOCK(pub);
+
flags = dhd_os_spin_lock(pub);
/* don't start the wd until fw is loaded */
if (pub->busstate == DHD_BUS_DOWN) {
dhd_os_spin_unlock(pub, flags);
+ DHD_OS_WD_WAKE_UNLOCK(pub);
return;
}
@@ -4000,6 +4013,7 @@ dhd_os_wd_timer(void *bus, uint wdtick)
#else
del_timer(&dhd->timer);
#endif /* DHDTHREAD */
+ DHD_OS_WD_WAKE_UNLOCK(pub);
return;
}
@@ -4877,6 +4891,44 @@ int net_os_wake_unlock(struct net_device *dev)
return ret;
}
+int dhd_os_wd_wake_lock(dhd_pub_t *pub)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+ unsigned long flags;
+ int ret = 0;
+
+ if (dhd) {
+ spin_lock_irqsave(&dhd->wakelock_spinlock, flags);
+#ifdef CONFIG_HAS_WAKELOCK
+ if (!dhd->wakelock_wd_counter)
+ wake_lock(&dhd->wl_wdwake);
+#endif
+ dhd->wakelock_wd_counter++;
+ ret = dhd->wakelock_wd_counter;
+ spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags);
+ }
+ return ret;
+}
+
+int dhd_os_wd_wake_unlock(dhd_pub_t *pub)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+ unsigned long flags;
+ int ret = 0;
+
+ if (dhd) {
+ spin_lock_irqsave(&dhd->wakelock_spinlock, flags);
+ if (dhd->wakelock_wd_counter) {
+ dhd->wakelock_wd_counter = 0;
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_unlock(&dhd->wl_wdwake);
+#endif
+ }
+ spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags);
+ }
+ return ret;
+}
+
int dhd_os_check_if_up(void *dhdp)
{
dhd_pub_t *pub = (dhd_pub_t *)dhdp;
diff --git a/drivers/net/wireless/bcmdhd/include/bcmutils.h b/drivers/net/wireless/bcmdhd/include/bcmutils.h
index 6849c26..a570fa2 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmutils.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmutils.h
@@ -603,6 +603,8 @@ extern void *_bcmutils_dummy_fn;
#define CRC32_INIT_VALUE 0xffffffff
#define CRC32_GOOD_VALUE 0xdebb20e3
+#define MACDBG "%02x:%02x:%02x:%02x:%02x:%02x"
+#define MAC2STRDBG(ea) (ea)[0], (ea)[1], (ea)[2], (ea)[3], (ea)[4], (ea)[5]
typedef struct bcm_bit_desc {
uint32 bit;
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index 5d4eaa9..3b9ca46 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -1870,6 +1870,7 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
/* Clean BSSID */
bzero(&bssid, sizeof(bssid));
wl_update_prof(wl, dev, NULL, (void *)&bssid, WL_PROF_BSSID);
+ wl_update_prof(wl, dev, NULL, params->bssid, WL_PROF_PENDING_BSSID);
if (params->ssid)
WL_INFO(("SSID: %s\n", params->ssid));
@@ -2341,6 +2342,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
/* Clean BSSID */
bzero(&bssid, sizeof(bssid));
wl_update_prof(wl, dev, NULL, (void *)&bssid, WL_PROF_BSSID);
+ wl_update_prof(wl, dev, NULL, sme->bssid, WL_PROF_PENDING_BSSID);
if (IS_P2P_SSID(sme->ssid) && (dev != wl_to_prmry_ndev(wl))) {
/* we only allow to connect using virtual interface in case of P2P */
@@ -5145,7 +5147,8 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
WL_DBG(("wl_ibss_join_done succeeded\n"));
} else {
if (!wl_get_drv_status(wl, DISCONNECTING, ndev)) {
- printk("wl_bss_connect_done succeeded\n");
+ printk("wl_bss_connect_done succeeded with " MACDBG "\n",
+ MAC2STRDBG((u8*)(&e->addr)));
wl_bss_connect_done(wl, ndev, e, data, true);
WL_DBG(("joined in BSS network \"%s\"\n",
((struct wlc_ssid *)
@@ -5194,8 +5197,8 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
wl_clr_drv_status(wl, DISCONNECTING, ndev);
} else if (wl_is_nonetwork(wl, e)) {
- printk("connect failed event=%d e->status 0x%x\n",
- event, (int)ntoh32(e->status));
+ printk("connect failed event=%d e->status %d e->reason %d\n",
+ event, (int)ntoh32(e->status), (int)ntoh32(e->reason));
/* Clean up any pending scan request */
if (wl->scan_request) {
if (wl->escan_on) {
@@ -5455,9 +5458,17 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
u8 *curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
WL_DBG((" enter\n"));
+
if (wl->scan_request) {
wl_notify_escan_complete(wl, ndev, true, true);
}
+ if (is_zero_ether_addr(curbssid)) {
+ curbssid = wl_read_prof(wl, ndev, WL_PROF_PENDING_BSSID);
+ if (is_zero_ether_addr(curbssid)) {
+ WL_ERR(("Invalid BSSID\n"));
+ curbssid = NULL;
+ }
+ }
if (wl_get_drv_status(wl, CONNECTING, ndev)) {
wl_clr_drv_status(wl, CONNECTING, ndev);
if (completed) {
@@ -5474,7 +5485,9 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
conn_info->req_ie_len,
conn_info->resp_ie,
conn_info->resp_ie_len,
- completed ? WLAN_STATUS_SUCCESS : e->reason,
+ completed ? WLAN_STATUS_SUCCESS :
+ (e->reason) ? ntoh32(e->reason) :
+ WLAN_STATUS_UNSPECIFIED_FAILURE,
GFP_KERNEL);
if (completed)
WL_INFO(("Report connect result - connection succeeded\n"));
@@ -7472,6 +7485,9 @@ static void *wl_read_prof(struct wl_priv *wl, struct net_device *ndev, s32 item)
case WL_PROF_BSSID:
rptr = profile->bssid;
break;
+ case WL_PROF_PENDING_BSSID:
+ rptr = profile->pending_bssid;
+ break;
case WL_PROF_SSID:
rptr = &profile->ssid;
break;
@@ -7508,6 +7524,12 @@ wl_update_prof(struct wl_priv *wl, struct net_device *ndev,
else
memset(profile->bssid, 0, ETHER_ADDR_LEN);
break;
+ case WL_PROF_PENDING_BSSID:
+ if (data)
+ memcpy(profile->pending_bssid, data, ETHER_ADDR_LEN);
+ else
+ memset(profile->pending_bssid, 0, ETHER_ADDR_LEN);
+ break;
case WL_PROF_SEC:
memcpy(&profile->sec, data, sizeof(profile->sec));
break;
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
index 07161be..0c0c1e5 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.h
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
@@ -183,6 +183,7 @@ enum wl_prof_list {
WL_PROF_IBSS,
WL_PROF_BAND,
WL_PROF_BSSID,
+ WL_PROF_PENDING_BSSID,
WL_PROF_ACT,
WL_PROF_BEACONINT,
WL_PROF_DTIMPERIOD
@@ -285,6 +286,7 @@ struct wl_profile {
struct wl_security sec;
struct wl_ibss ibss;
u8 bssid[ETHER_ADDR_LEN];
+ u8 pending_bssid[ETHER_ADDR_LEN];
u16 beacon_interval;
u8 dtim_period;
bool active;