aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2013-05-10 12:20:18 -0700
committerZiyan <jaraidaniel@gmail.com>2016-05-01 23:35:18 +0200
commit627a4c370d44dfa61eaf7c851603e4aea12cddea (patch)
treec19473ec5925a89c861bba260b7b325df57366b2 /drivers
parent5be65b955278956db4cb99f58b5a3309864480f1 (diff)
downloadkernel_samsung_tuna-627a4c370d44dfa61eaf7c851603e4aea12cddea.zip
kernel_samsung_tuna-627a4c370d44dfa61eaf7c851603e4aea12cddea.tar.gz
kernel_samsung_tuna-627a4c370d44dfa61eaf7c851603e4aea12cddea.tar.bz2
net: wireless: bcmdhd: Update to version 1.88.16
- Change the logic to enable Power save mode for STA or P2P GC - Fix protxstatus bug for corner case - Reset uninitialized value for mac entry - Remove dhd_wlfc_init/deinit in wl_android.c - Fix IBSS mode Change-Id: I4589e87eda456798eae48548261a1f7cb9542660 Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/bcmdhd/dhd.h6
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_cdc.c7
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_linux.c10
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_sdio.c4
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_wlfc.c17
-rw-r--r--drivers/net/wireless/bcmdhd/include/epivers.h14
-rw-r--r--drivers/net/wireless/bcmdhd/wl_android.c12
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.c185
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.h6
9 files changed, 196 insertions, 65 deletions
diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h
index 290fc31..9249f0b 100644
--- a/drivers/net/wireless/bcmdhd/dhd.h
+++ b/drivers/net/wireless/bcmdhd/dhd.h
@@ -24,7 +24,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.h 393288 2013-03-27 01:02:25Z $
+ * $Id: dhd.h 397286 2013-04-18 01:42:19Z $
*/
/****************
@@ -478,6 +478,9 @@ extern void dhd_free(dhd_pub_t *dhdp);
/* Indication from bus module to change flow-control state */
extern void dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool on);
+/* Store the status of a connection attempt for later retrieval by an iovar */
+extern void dhd_store_conn_status(uint32 event, uint32 status, uint32 reason);
+
extern bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec);
/* Receive frame for delivery to OS. Callee disposes of rxp. */
@@ -588,6 +591,7 @@ extern int dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifindex, wl_ioctl_t *ioc, void *
extern int dhd_wl_ioctl_cmd(dhd_pub_t *dhd_pub, int cmd, void *arg, int len, uint8 set,
int ifindex);
extern void dhd_common_init(osl_t *osh);
+extern void dhd_common_deinit(dhd_pub_t *dhd_pub, dhd_cmn_t *sa_cmn);
extern int dhd_do_driver_init(struct net_device *net);
extern int dhd_add_if(struct dhd_info *dhd, int ifidx, void *handle,
diff --git a/drivers/net/wireless/bcmdhd/dhd_cdc.c b/drivers/net/wireless/bcmdhd/dhd_cdc.c
index dc7a668..f341a1f 100644
--- a/drivers/net/wireless/bcmdhd/dhd_cdc.c
+++ b/drivers/net/wireless/bcmdhd/dhd_cdc.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_cdc.c 393623 2013-03-28 06:27:09Z $
+ * $Id: dhd_cdc.c 401089 2013-05-08 18:17:31Z $
*
* BDC is like CDC, except it includes a header for data packets to convey
* packet priority over the bus, and flags (e.g. to indicate checksum status
@@ -558,11 +558,6 @@ dhd_prot_init(dhd_pub_t *dhd)
if (dhd_download_fw_on_driverload)
#endif /* defined(WL_CFG80211) */
ret = dhd_preinit_ioctls(dhd);
-
-#ifdef PROP_TXSTATUS
- ret = dhd_wlfc_init(dhd);
-#endif
-
/* Always assumes wl for now */
dhd->iswl = TRUE;
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index b47ff7e..f5506a4 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -22,7 +22,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_linux.c 397043 2013-04-17 02:56:29Z $
+ * $Id: dhd_linux.c 401270 2013-05-09 11:58:40Z $
*/
#include <typedefs.h>
@@ -3825,6 +3825,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
setbit(eventmask, WLC_E_DISASSOC_IND);
setbit(eventmask, WLC_E_DISASSOC);
setbit(eventmask, WLC_E_JOIN);
+ setbit(eventmask, WLC_E_START);
setbit(eventmask, WLC_E_ASSOC_IND);
setbit(eventmask, WLC_E_PSK_SUP);
setbit(eventmask, WLC_E_LINK);
@@ -3918,6 +3919,10 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
#endif /* DISABLE_11N */
+#if defined(PROP_TXSTATUS) && !defined(PROP_TXSTATUS_VSDB)
+ dhd_wlfc_init(dhd);
+#endif /* PROP_TXSTATUS && !PROP_TXSTATUS_VSDB */
+
/* query for 'ver' to get version info from firmware */
memset(buf, 0, sizeof(buf));
ptr = buf;
@@ -5022,6 +5027,9 @@ dhd_dev_reset(struct net_device *dev, uint8 flag)
if (dhd_wl_ioctl_cmd(&dhd->pub, WLC_DOWN, NULL, 0, TRUE, 0) < 0) {
DHD_TRACE(("%s: wl down failed\n", __FUNCTION__));
}
+#if defined(PROP_TXSTATUS) && !defined(PROP_TXSTATUS_VSDB)
+ dhd_wlfc_deinit(&dhd->pub);
+#endif /* PROP_TXSTATUS && !PROP_TXSTATUS_VSDB */
}
ret = dhd_bus_devreset(&dhd->pub, flag);
diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c
index 64c8dfe..ad3ee95 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 392661 2013-03-22 23:17:02Z $
+ * $Id: dhd_sdio.c 399337 2013-04-29 23:39:03Z $
*/
#include <typedefs.h>
@@ -5797,7 +5797,7 @@ dhdsdio_isr(void *arg)
#if defined(SDIO_ISR_THREAD)
DHD_TRACE(("Calling dhdsdio_dpc() from %s\n", __FUNCTION__));
DHD_OS_WAKE_LOCK(bus->dhd);
- while (dhdsdio_dpc(bus));
+ dhdsdio_dpc(bus);
DHD_OS_WAKE_UNLOCK(bus->dhd);
#else
diff --git a/drivers/net/wireless/bcmdhd/dhd_wlfc.c b/drivers/net/wireless/bcmdhd/dhd_wlfc.c
index 540b8d8..9533856 100644
--- a/drivers/net/wireless/bcmdhd/dhd_wlfc.c
+++ b/drivers/net/wireless/bcmdhd/dhd_wlfc.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_wlfc.c 395161 2013-04-05 13:19:38Z $
+ * $Id: dhd_wlfc.c 400998 2013-05-08 09:04:02Z $
*
*/
@@ -1186,6 +1186,10 @@ _dhd_wlfc_mac_entry_update(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t*
entry->suppressed = 0;
entry->state = WLFC_STATE_CLOSE;
entry->requested_credit = 0;
+ entry->transit_count = 0;
+ entry->suppr_transit_count = 0;
+ entry->suppress_count = 0;
+ memset(&entry->ea[0], 0, ETHER_ADDR_LEN);
/* enable after packets are queued-deqeued properly.
pktq_flush(dhd->osh, &entry->psq, FALSE, NULL, 0);
@@ -1304,7 +1308,6 @@ _dhd_wlfc_handle_packet_commit(athost_wl_status_info_t* ctx, int ac,
return rc;
}
-
int
dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx, void *pktbuf)
{
@@ -1375,7 +1378,7 @@ dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx, vo
for (ac = AC_COUNT; ac >= 0; ac--) {
- int initial_credit_count = ctx->FIFO_credit[ac];
+ bool bQueueIdle = TRUE;
/* packets from delayQ with less priority are fresh and they'd need header and
* have no MAC entry
@@ -1393,6 +1396,8 @@ dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx, vo
if (commit_info.p == NULL)
break;
+ bQueueIdle = FALSE;
+
commit_info.pkt_type = (commit_info.needs_hdr) ? eWLFC_PKTTYPE_DELAYED :
eWLFC_PKTTYPE_SUPPRESSED;
@@ -1418,10 +1423,8 @@ dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx, vo
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]) {
+ /* If no pkts can be dequed, the credit can be borrowed */
+ if (bQueueIdle) {
ac_available |= (1 << ac);
credit_count += ctx->FIFO_credit[ac];
}
diff --git a/drivers/net/wireless/bcmdhd/include/epivers.h b/drivers/net/wireless/bcmdhd/include/epivers.h
index 7e96ec8..d2c5388 100644
--- a/drivers/net/wireless/bcmdhd/include/epivers.h
+++ b/drivers/net/wireless/bcmdhd/include/epivers.h
@@ -30,26 +30,26 @@
#define EPI_MINOR_VERSION 88
-#define EPI_RC_NUMBER 11
+#define EPI_RC_NUMBER 16
#define EPI_INCREMENTAL_NUMBER 0
#define EPI_BUILD_NUMBER 0
-#define EPI_VERSION 1, 88, 11, 0
+#define EPI_VERSION 1, 88, 16, 0
-#define EPI_VERSION_NUM 0x01580b00
+#define EPI_VERSION_NUM 0x01581000
-#define EPI_VERSION_DEV 1.88.11
+#define EPI_VERSION_DEV 1.88.16
/* Driver Version String, ASCII, 32 chars max */
#ifdef BCMINTERNAL
-#define EPI_VERSION_STR "1.88.11 (r BCMINT)"
+#define EPI_VERSION_STR "1.88.16 (r BCMINT)"
#else
#ifdef WLTEST
-#define EPI_VERSION_STR "1.88.11 (r WLTEST)"
+#define EPI_VERSION_STR "1.88.16 (r WLTEST)"
#else
-#define EPI_VERSION_STR "1.88.11 (r)"
+#define EPI_VERSION_STR "1.88.16 (r)"
#endif
#endif /* BCMINTERNAL */
diff --git a/drivers/net/wireless/bcmdhd/wl_android.c b/drivers/net/wireless/bcmdhd/wl_android.c
index 935397f..68fb212 100644
--- a/drivers/net/wireless/bcmdhd/wl_android.c
+++ b/drivers/net/wireless/bcmdhd/wl_android.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: wl_android.c 397123 2013-04-17 08:59:26Z $
+ * $Id: wl_android.c 399333 2013-04-29 23:26:59Z $
*/
#include <linux/module.h>
@@ -168,10 +168,6 @@ extern int dhd_os_check_if_up(void *dhdp);
#ifdef BCMLXSDMMC
extern void *bcmsdh_get_drvdata(void);
#endif /* BCMLXSDMMC */
-#if defined(PROP_TXSTATUS) && !defined(PROP_TXSTATUS_VSDB)
-extern int dhd_wlfc_init(dhd_pub_t *dhd);
-extern void dhd_wlfc_deinit(dhd_pub_t *dhd);
-#endif
#ifdef ENABLE_4335BT_WAR
@@ -455,9 +451,6 @@ int wl_android_wifi_on(struct net_device *dev)
if (dhd_dev_init_ioctl(dev) < 0)
ret = -EFAULT;
}
-#if defined(PROP_TXSTATUS) && !defined(PROP_TXSTATUS_VSDB) && defined(BCMLXSDMMC)
- dhd_wlfc_init(bcmsdh_get_drvdata());
-#endif
g_wifi_on = TRUE;
}
@@ -479,9 +472,6 @@ int wl_android_wifi_off(struct net_device *dev)
dhd_net_if_lock(dev);
if (g_wifi_on) {
-#if defined(PROP_TXSTATUS) && !defined(PROP_TXSTATUS_VSDB) && defined(BCMLXSDMMC)
- dhd_wlfc_deinit(bcmsdh_get_drvdata());
-#endif
ret = dhd_dev_reset(dev, TRUE);
sdioh_stop(NULL);
dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index e4c5259..47751c0 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.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: wl_cfg80211.c 396645 2013-04-15 06:51:13Z $
+ * $Id: wl_cfg80211.c 401050 2013-05-08 13:36:28Z $
*/
#include <typedefs.h>
#include <linuxver.h>
@@ -202,8 +202,7 @@ static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
u16 reason_code);
static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
- enum nl80211_tx_power_setting type,
- s32 dbm);
+ enum nl80211_tx_power_setting type, s32 dbm);
static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
struct net_device *dev,
@@ -361,6 +360,7 @@ static void wl_cfg80211_work_handler(struct work_struct *work);
static void wl_cfg80211_scan_supp_timerfunc(ulong data);
#endif /* DHCP_SCAN_SUPPRESS */
+static void wl_cfg80211_work_handler(struct work_struct *work);
static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
u8 key_idx, const u8 *mac_addr,
struct key_params *params);
@@ -1229,6 +1229,11 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
}
wldev_iovar_setint(dev, "mpc", 1);
+ if (wl->pm_enable_work_on) {
+ cancel_delayed_work_sync(&wl->pm_enable_work);
+ wl->pm_enable_work_on = false;
+ }
+
/* for GC */
if (wl_get_drv_status(wl, DISCONNECTING, dev) &&
(wl_get_mode_by_netdev(wl, dev) != WL_MODE_AP)) {
@@ -1297,8 +1302,10 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
{
s32 ap = 0;
s32 infra = 0;
+ s32 ibss = 0;
s32 wlif_type;
s32 mode = 0;
+ s32 err = BCME_OK;
chanspec_t chspec;
struct wl_priv *wl = wiphy_priv(wiphy);
dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
@@ -1313,6 +1320,7 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
break;
case NL80211_IFTYPE_ADHOC:
mode = WL_MODE_IBSS;
+ ibss = 1;
break;
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_P2P_CLIENT:
@@ -1376,6 +1384,16 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
WL_DBG(("Change_virtual_iface for transition from GO/AP to client/STA"));
}
+ if (ibss) {
+ infra = 0;
+ wl_set_mode_by_netdev(wl, ndev, mode);
+ err = wldev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(s32), true);
+ if (err < 0) {
+ WL_ERR(("SET Adhoc error %d\n", err));
+ return -EINVAL;
+ }
+ }
+
ndev->ieee80211_ptr->iftype = type;
return 0;
}
@@ -3029,7 +3047,7 @@ wl_cfg80211_set_tx_power(struct wiphy *wiphy,
u16 txpwrmw;
s32 err = 0;
s32 disable = 0;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) || defined(WL_COMPAT_WIRELESS)
dbm = MBM_TO_DBM(dbm);
#endif
@@ -3570,12 +3588,24 @@ wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
#endif
RETURN_EIO_IF_NOT_UP(wl);
-
- if (wl->p2p_net == dev || _net_info == NULL || wl->vsdb_mode) {
+ WL_DBG(("Enter\n"));
+#if defined(WL_ENABLE_P2P_IF)
+ if (wl->p2p_net == dev || _net_info == NULL || wl->vsdb_mode ||
+ !wl_get_drv_status(wl, CONNECTED, dev)) {
+#else
+ if (_net_info == NULL || wl->vsdb_mode ||
+ !wl_get_drv_status(wl, CONNECTED, dev)) {
+#endif /* WL_ENABLE_P2P_IF */
return err;
}
WL_DBG(("%s: Enter power save enabled %d\n", dev->name, enabled));
+ /* Delete pm_enable_work */
+ if (wl->pm_enable_work_on) {
+ cancel_delayed_work_sync(&wl->pm_enable_work);
+ wl->pm_enable_work_on = false;
+ }
+
#if !defined(SUPPORT_PM2_ONLY)
/* android has special hooks to change pm when kernel suspended */
pm = enabled ? ((dhd->in_suspend) ? PM_MAX : PM_FAST) : PM_OFF;
@@ -3583,9 +3613,8 @@ wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
pm = enabled ? PM_FAST : PM_OFF;
#endif /* SUPPORT_PM2_ONLY */
if (_net_info->pm_block) {
- /* Do not enable the power save if it is p2p interface or vsdb mode is set */
- WL_DBG(("%s:Do not enable the power save for pm_block %d or vsdb_mode %d\n",
- dev->name, _net_info->pm_block, wl->vsdb_mode));
+ WL_ERR(("%s:Do not enable the power save for pm_block %d\n",
+ dev->name, _net_info->pm_block));
pm = PM_OFF;
}
pm = htod32(pm);
@@ -6053,6 +6082,7 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev
#endif /* WL_SCHED_SCAN */
wdev->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION)
+ | BIT(NL80211_IFTYPE_ADHOC)
#if !defined(WL_ENABLE_P2P_IF)
| BIT(NL80211_IFTYPE_MONITOR)
#endif /* !WL_ENABLE_P2P_IF */
@@ -6245,7 +6275,7 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi, u8 i
offsetof(struct wl_cfg80211_bss_info, frame_buf));
notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt,
u.beacon.variable) + wl_get_ielen(wl);
-#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38)
freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
(void)band->band;
#else
@@ -6552,7 +6582,7 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
wl_notify_connect_status_ap(wl, ndev, e, data);
- } else {
+ } else if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_BSS) {
WL_DBG(("wl_notify_connect_status : event %d status : %d ndev %p\n",
ntoh32(e->event_type), ntoh32(e->status), ndev));
if (event == WLC_E_ASSOC || event == WLC_E_AUTH) {
@@ -6562,20 +6592,13 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
if (wl_is_linkup(wl, e, ndev)) {
wl_link_up(wl);
act = true;
- if (wl_is_ibssmode(wl, ndev)) {
- printk("cfg80211_ibss_joined\n");
- cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
- GFP_KERNEL);
- WL_DBG(("joined in IBSS network\n"));
- } else {
- if (!wl_get_drv_status(wl, DISCONNECTING, ndev)) {
+ if (!wl_get_drv_status(wl, DISCONNECTING, ndev)) {
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 *)
wl_read_prof(wl, ndev, WL_PROF_SSID))->SSID));
- }
}
wl_update_prof(wl, ndev, e, &act, WL_PROF_ACT);
wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID);
@@ -6659,7 +6682,38 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
if (wl_get_drv_status(wl, CONNECTING, ndev))
wl_bss_connect_done(wl, ndev, e, data, false);
} else {
- printk("%s nothing\n", __FUNCTION__);
+ WL_DBG(("%s nothing\n", __FUNCTION__));
+ }
+ } else if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_IBSS) {
+ u16 flags = ntoh16(e->flags);
+ u32 status = ntoh32(e->status);
+ struct wl_profile *profile = wl_get_profile_by_netdev(wl, ndev);
+
+ if (event == WLC_E_JOIN) {
+ WL_DBG(("joined in IBSS network\n"));
+ }
+ if (event == WLC_E_START) {
+ WL_DBG(("started IBSS network\n"));
+ }
+ if (event == WLC_E_JOIN || event == WLC_E_START) {
+ wl_link_up(wl);
+ wl_get_assoc_ies(wl, ndev);
+ wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID);
+ wl_update_bss_info(wl, ndev, 1);
+ cfg80211_ibss_joined(ndev, (s8 *)&e->addr, GFP_KERNEL);
+ wl_set_drv_status(wl, CONNECTED, ndev);
+ profile->active = true;
+ } else if ((event == WLC_E_LINK && !(flags & WLC_EVENT_MSG_LINK)) ||
+ event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) {
+ wl_clr_drv_status(wl, CONNECTED, ndev);
+ wl_link_down(wl);
+ wl_init_prof(wl, ndev);
+ }
+ else if (event == WLC_E_SET_SSID && status == WLC_E_STATUS_NO_NETWORKS) {
+ WL_DBG(("no action - join fail (IBSS mode)\n"));
+ }
+ else {
+ WL_DBG(("no action (IBSS mode)\n"));
}
}
return err;
@@ -6805,9 +6859,6 @@ static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev, u8 is
wiphy = wl_to_wiphy(wl);
- if (wl_is_ibssmode(wl, ndev))
- return err;
-
ssid = (struct wlc_ssid *)wl_read_prof(wl, ndev, WL_PROF_SSID);
curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
bss = cfg80211_get_bss(wiphy, NULL, curbssid,
@@ -7216,7 +7267,7 @@ wl_notify_rx_mgmt_frame(struct wl_priv *wl, struct net_device *ndev,
WL_ERR(("No valid band"));
return -EINVAL;
}
-#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38)
freq = ieee80211_channel_to_frequency(channel);
(void)band->band;
#else
@@ -7502,6 +7553,8 @@ static void wl_init_event_handler(struct wl_priv *wl)
wl->evt_handler[WLC_E_P2P_DISC_LISTEN_COMPLETE] = wl_cfgp2p_listen_complete;
wl->evt_handler[WLC_E_ACTION_FRAME_COMPLETE] = wl_cfgp2p_action_tx_complete;
wl->evt_handler[WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE] = wl_cfgp2p_action_tx_complete;
+ wl->evt_handler[WLC_E_JOIN] = wl_notify_connect_status;
+ wl->evt_handler[WLC_E_START] = wl_notify_connect_status;
#ifdef PNO_SUPPORT
wl->evt_handler[WLC_E_PFN_NET_FOUND] = wl_notify_pfn_status;
#endif /* PNO_SUPPORT */
@@ -8397,11 +8450,13 @@ static void wl_cfg80211_determine_vsdb_mode(struct wl_priv *wl)
}
return;
}
+
static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_info,
enum wl_status state, bool set)
{
s32 pm = PM_FAST;
s32 err = BCME_OK;
+ u32 mode;
u32 chan = 0;
struct net_info *iter, *next;
struct net_device *primary_dev = wl_to_prmry_ndev(wl);
@@ -8410,17 +8465,28 @@ static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_in
if (state != WL_STATUS_CONNECTED)
return 0;
-
+ mode = wl_get_mode_by_netdev(wl, _net_info->ndev);
if (set) {
wl_cfg80211_concurrent_roam(wl, 1);
- if (wl_get_mode_by_netdev(wl, _net_info->ndev) == WL_MODE_AP) {
+ if (mode == WL_MODE_AP) {
if (wl_add_remove_eventmsg(primary_dev, WLC_E_P2P_PROBREQ_MSG, false))
WL_ERR((" failed to unset WLC_E_P2P_PROPREQ_MSG\n"));
}
wl_cfg80211_determine_vsdb_mode(wl);
if (wl->vsdb_mode || _net_info->pm_block) {
+ if (wl->pm_enable_work_on) {
+ cancel_delayed_work_sync(&wl->pm_enable_work);
+ wl->pm_enable_work_on = false;
+ }
+ /* save PM_FAST in _net_info to restore this
+ * if _net_info->pm_block is false
+ */
+ if (!_net_info->pm_block && (mode == WL_MODE_BSS)) {
+ _net_info->pm = PM_FAST;
+ _net_info->pm_restore = true;
+ }
pm = PM_OFF;
for_each_ndev(wl, iter, next) {
if (iter->pm_restore)
@@ -8442,9 +8508,33 @@ static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_in
WL_DBG(("%s:netdev not ready\n", iter->ndev->name));
else
WL_ERR(("%s:error (%d)\n", iter->ndev->name, err));
+ } else
iter->ndev->ieee80211_ptr->ps = false;
+ }
+ } else {
+ /* add PM Enable timer to go to power save mode
+ * if supplicant control pm mode, it will be cleared or
+ * updated by wl_cfg80211_set_power_mgmt() if not - for static IP & HW4 P2P,
+ * PM will be configured when timer expired
+ */
+
+ /*
+ * before calling pm_enable_timer, we need to set PM -1 for all ndev
+ */
+ pm = PM_OFF;
+
+ for_each_ndev(wl, iter, next) {
+ if ((err = wldev_ioctl(iter->ndev, WLC_SET_PM, &pm,
+ sizeof(pm), true)) != 0) {
+ if (err == -ENODEV)
+ WL_DBG(("%s:netdev not ready\n", iter->ndev->name));
+ else
+ WL_ERR(("%s:error (%d)\n", iter->ndev->name, err));
}
}
+ wl->pm_enable_work_on = true;
+ schedule_delayed_work(&wl->pm_enable_work,
+ msecs_to_jiffies(WL_PM_ENABLE_TIMEOUT));
}
}
else { /* clear */
@@ -9194,7 +9284,7 @@ static int wl_construct_reginfo(struct wl_priv *wl, s32 bw_cap)
else
index = *n_cnt;
if (index < array_size) {
-#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38)
band_chan_arr[index].center_freq =
ieee80211_channel_to_frequency(channel);
#else
@@ -9391,7 +9481,7 @@ static s32 __wl_cfg80211_up(struct wl_priv *wl)
wl->scan_supp_timer.function = wl_cfg80211_scan_supp_timerfunc;
INIT_WORK(&wl->wlan_work, wl_cfg80211_work_handler);
#endif /* DHCP_SCAN_SUPPRESS */
-
+ INIT_DELAYED_WORK(&wl->pm_enable_work, wl_cfg80211_work_handler);
wl_set_drv_status(wl, READY, ndev);
return err;
}
@@ -9404,6 +9494,10 @@ static s32 __wl_cfg80211_down(struct wl_priv *wl)
struct net_device *ndev = wl_to_prmry_ndev(wl);
u32 bssidx = 0;
WL_DBG(("In\n"));
+ if (wl->pm_enable_work_on) {
+ cancel_delayed_work_sync(&wl->pm_enable_work);
+ wl->pm_enable_work_on = false;
+ }
#if defined(DHCP_SCAN_SUPPRESS)
/* Force clear of scan_suppress */
@@ -9781,7 +9875,7 @@ s32 wl_cfg80211_channel_to_freq(u32 channel)
{
int freq = 0;
-#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38)
freq = ieee80211_channel_to_frequency(channel);
#else
{
@@ -10544,3 +10638,36 @@ int wl_cfg80211_scan_suppress(struct net_device *dev, int suppress)
return ret;
}
#endif /* DHCP_SCAN_SUPPRESS */
+
+static void wl_cfg80211_work_handler(struct work_struct * work)
+{
+ struct wl_priv *wl = NULL;
+ struct net_info *iter, *next;
+ s32 err = BCME_OK;
+ s32 pm = PM_FAST;
+
+ wl = container_of(work, struct wl_priv, pm_enable_work.work);
+ WL_DBG(("Enter \n"));
+ if (!wl) {
+ WL_ERR(("wl_priv ptr NULL"));
+ return;
+ }
+ if (wl->pm_enable_work_on) {
+ wl->pm_enable_work_on = false;
+ for_each_ndev(wl, iter, next) {
+ if (!wl_get_drv_status(wl, CONNECTED, iter->ndev) ||
+ (wl_get_mode_by_netdev(wl, iter->ndev) != WL_MODE_BSS))
+ continue;
+ if (iter->ndev) {
+ if ((err = wldev_ioctl(iter->ndev, WLC_SET_PM,
+ &pm, sizeof(pm), true)) != 0) {
+ if (err == -ENODEV)
+ WL_DBG(("%s:netdev not ready\n", iter->ndev->name));
+ else
+ WL_ERR(("%s:error (%d)\n", iter->ndev->name, err));
+ } else
+ iter->ndev->ieee80211_ptr->ps = true;
+ }
+ }
+ }
+}
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
index 8840b20..61e1c09 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.h
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
@@ -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: wl_cfg80211.h 389705 2013-03-07 20:04:22Z $
+ * $Id: wl_cfg80211.h 401050 2013-05-08 13:36:28Z $
*/
#ifndef _wl_cfg80211_h_
@@ -172,6 +172,8 @@ do { \
#define WL_SCAN_SUPPRESS_TIMEOUT 31000 /* default Framwork DHCP timeout is 30 sec */
#define WL_SCAN_SUPPRESS_RETRY 3000
+#define WL_PM_ENABLE_TIMEOUT 3000
+
/* driver status */
enum wl_status {
WL_STATUS_READY = 0,
@@ -578,6 +580,8 @@ struct wl_priv {
struct timer_list scan_supp_timer;
struct work_struct wlan_work;
struct mutex event_sync; /* maily for up/down synchronization */
+ bool pm_enable_work_on;
+ struct delayed_work pm_enable_work;
};