summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/bcmdhd
diff options
context:
space:
mode:
authorHoward M. Harte <hharte@broadcom.com>2011-07-25 19:15:11 -0700
committerJonas ABERG <jonas.aberg@stericsson.com>2011-10-28 11:00:00 +0200
commit9507fa86cdb8ed22dee4067dcbaf600e6f60cdf0 (patch)
tree1147f0810ba79ca3ce699548b45477c3116e9679 /drivers/net/wireless/bcmdhd
parent6d6fb2996b129a247304229b9cbbcdb908680595 (diff)
Update to 5.90.125.52:
Fix unremoved monitor interface problem after killing hostapd. Add WPS support for hostapd. Change-Id: I4e476fafb203592fcdf5c15a526b67d4aa78df3e Signed-off-by: Howard M. Harte <hharte@broadcom.com> Signed-off-by: Dmitry Shmidt <dimitrysh@google.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/35556 Tested-by: Per VAHLNE <per.xx.vahlne@stericsson.com> Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
Diffstat (limited to 'drivers/net/wireless/bcmdhd')
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_bus.h1
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_linux.c3
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_linux_mon.c163
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_sdio.c12
-rw-r--r--drivers/net/wireless/bcmdhd/include/epivers.h8
-rw-r--r--drivers/net/wireless/bcmdhd/wl_android.c17
-rw-r--r--drivers/net/wireless/bcmdhd/wl_android.h4
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.c203
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfgp2p.c20
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfgp2p.h4
10 files changed, 274 insertions, 161 deletions
diff --git a/drivers/net/wireless/bcmdhd/dhd_bus.h b/drivers/net/wireless/bcmdhd/dhd_bus.h
index bae0713948b..294322026e9 100644
--- a/drivers/net/wireless/bcmdhd/dhd_bus.h
+++ b/drivers/net/wireless/bcmdhd/dhd_bus.h
@@ -59,6 +59,7 @@ extern int dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen);
/* Watchdog timer function */
extern bool dhd_bus_watchdog(dhd_pub_t *dhd);
+extern void dhd_disable_intr(dhd_pub_t *dhd);
#if defined(DHD_DEBUG)
/* Device console input function */
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index e318017ff80..690384a2495 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -3248,6 +3248,9 @@ dhd_module_init(void)
goto fail_2;
}
#endif
+#if defined(WL_CFG80211)
+ error = wl_android_post_init();
+#endif
return error;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && 1
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux_mon.c b/drivers/net/wireless/bcmdhd/dhd_linux_mon.c
index a51db01a870..25eba63017f 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux_mon.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux_mon.c
@@ -30,6 +30,7 @@
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
#include <linux/ieee80211.h>
+#include <linux/rtnetlink.h>
#include <net/ieee80211_radiotap.h>
#include <wlioctl.h>
@@ -39,10 +40,14 @@
#include <dngl_stats.h>
#include <dhd.h>
-/*
- * Some external functions, TODO: move them to dhd_linux.h
- */
-int dhd_start_xmit(struct sk_buff *skb, struct net_device *net);
+typedef enum monitor_states
+{
+ MONITOR_STATE_DEINIT = 0x0,
+ MONITOR_STATE_INIT = 0x1,
+ MONITOR_STATE_INTERFACE_ADDED = 0x2,
+ MONITOR_STATE_INTERFACE_DELETED = 0x4
+} monitor_states_t;
+extern int dhd_start_xmit(struct sk_buff *skb, struct net_device *net);
/**
* Local declarations and defintions (not exposed)
@@ -58,9 +63,9 @@ typedef struct monitor_interface {
typedef struct dhd_linux_monitor {
void *dhd_pub;
+ monitor_states_t monitor_state;
monitor_interface mon_if[DHD_MAX_IFS];
- int count; /* Number of total monitor interface */
- struct mutex lock; /* lock to protect count and mon_if */
+ struct mutex lock; /* lock to protect mon_if */
} dhd_linux_monitor_t;
static dhd_linux_monitor_t g_monitor;
@@ -145,6 +150,7 @@ static int dhd_mon_if_subif_start_xmit(struct sk_buff *skb, struct net_device *n
int dot11_hdr_len = 24;
int snap_len = 6;
unsigned char *pdata;
+ unsigned short frame_ctl;
unsigned char src_mac_addr[6];
unsigned char dst_mac_addr[6];
struct ieee80211_hdr *dot11_hdr;
@@ -176,35 +182,35 @@ static int dhd_mon_if_subif_start_xmit(struct sk_buff *skb, struct net_device *n
skb_pull(skb, rtap_len);
dot11_hdr = (struct ieee80211_hdr *)skb->data;
-
+ frame_ctl = le16_to_cpu(dot11_hdr->frame_control);
/* Check if the QoS bit is set */
- if (dot11_hdr->frame_control & 0x0080)
- qos_len = 2;
-
- /* Check if this ia a Wireless Distribution System (WDS) frame
- * which has 4 MAC addresses
- */
- if ((dot11_hdr->frame_control & 0x0300) == 0x0300)
- dot11_hdr_len += 6;
-
- memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
- memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
-
- /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for
- * for two MAC addresses
- */
- skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2);
- pdata = (unsigned char*)skb->data;
- memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr));
- memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr));
-
- MON_PRINT("if name: %s, matched if name %s\n", ndev->name, mon_if->real_ndev->name);
-
- /* Use the real net device to transmit the packet */
- ret = dhd_start_xmit(skb, mon_if->real_ndev);
-
- return ret;
-
+ if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
+ /* Check if this ia a Wireless Distribution System (WDS) frame
+ * which has 4 MAC addresses
+ */
+ if (dot11_hdr->frame_control & 0x0080)
+ qos_len = 2;
+ if ((dot11_hdr->frame_control & 0x0300) == 0x0300)
+ dot11_hdr_len += 6;
+
+ memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
+ memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
+
+ /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for
+ * for two MAC addresses
+ */
+ skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2);
+ pdata = (unsigned char*)skb->data;
+ memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr));
+ memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr));
+
+ MON_PRINT("if name: %s, matched if name %s\n", ndev->name, mon_if->real_ndev->name);
+
+ /* Use the real net device to transmit the packet */
+ ret = dhd_start_xmit(skb, mon_if->real_ndev);
+
+ return ret;
+ }
fail:
dev_kfree_skb(skb);
return 0;
@@ -242,7 +248,8 @@ static int dhd_mon_if_change_mac(struct net_device *ndev, void *addr)
int dhd_add_monitor(char *name, struct net_device **new_ndev)
{
- int idx;
+ int i;
+ int idx = -1;
int ret = 0;
struct net_device* ndev = NULL;
dhd_linux_monitor_t **dhd_mon;
@@ -256,7 +263,15 @@ int dhd_add_monitor(char *name, struct net_device **new_ndev)
goto out;
}
- if (g_monitor.count >= DHD_MAX_IFS) {
+ /*
+ * Find a vacancy
+ */
+ for (i = 0; i < DHD_MAX_IFS; i++)
+ if (g_monitor.mon_if[i].mon_ndev == NULL) {
+ idx = i;
+ break;
+ }
+ if (idx == -1) {
MON_PRINT("exceeds maximum interfaces\n");
ret = -EFAULT;
goto out;
@@ -281,14 +296,12 @@ int dhd_add_monitor(char *name, struct net_device **new_ndev)
}
*new_ndev = ndev;
- idx = g_monitor.count;
g_monitor.mon_if[idx].radiotap_enabled = TRUE;
g_monitor.mon_if[idx].mon_ndev = ndev;
g_monitor.mon_if[idx].real_ndev = lookup_real_netdev(name);
- g_monitor.count++;
dhd_mon = (dhd_linux_monitor_t **)netdev_priv(ndev);
*dhd_mon = &g_monitor;
-
+ g_monitor.monitor_state = MONITOR_STATE_INTERFACE_ADDED;
MON_PRINT("net device returned: 0x%p\n", ndev);
MON_PRINT("found a matched net device, name %s\n", g_monitor.mon_if[idx].real_ndev->name);
@@ -301,10 +314,48 @@ out:
}
+int dhd_del_monitor(struct net_device *ndev)
+{
+ int i;
+ bool rollback_lock = false;
+ if (!ndev)
+ return -EINVAL;
+ mutex_lock(&g_monitor.lock);
+ for (i = 0; i < DHD_MAX_IFS; i++) {
+ if (g_monitor.mon_if[i].mon_ndev == ndev) {
+ g_monitor.mon_if[i].real_ndev = NULL;
+ g_monitor.mon_if[i].mon_ndev = NULL;
+ if (rtnl_is_locked()) {
+ rtnl_unlock();
+ rollback_lock = true;
+ }
+ unregister_netdev(ndev);
+ free_netdev(ndev);
+ g_monitor.monitor_state = MONITOR_STATE_INTERFACE_DELETED;
+ ndev = NULL;
+ break;
+ }
+ }
+ if (rollback_lock) {
+ rtnl_lock();
+ rollback_lock = false;
+ }
+
+ if (ndev)
+ MON_PRINT("interface not found in monitor IF array, is this a monitor IF? 0x%p\n",
+ ndev);
+ mutex_unlock(&g_monitor.lock);
+
+ return 0;
+}
+
int dhd_monitor_init(void *dhd_pub)
{
- g_monitor.dhd_pub = dhd_pub;
- mutex_init(&g_monitor.lock);
+ if (g_monitor.monitor_state == MONITOR_STATE_DEINIT) {
+ g_monitor.dhd_pub = dhd_pub;
+ mutex_init(&g_monitor.lock);
+ g_monitor.monitor_state = MONITOR_STATE_INIT;
+ }
return 0;
}
@@ -312,20 +363,28 @@ int dhd_monitor_uninit(void)
{
int i;
struct net_device *ndev;
-
+ bool rollback_lock = false;
mutex_lock(&g_monitor.lock);
-
- for (i = 0; i < DHD_MAX_IFS; i++) {
- ndev = g_monitor.mon_if[i].mon_ndev;
- if (ndev) {
- unregister_netdev(ndev);
- free_netdev(ndev);
- g_monitor.mon_if[i].real_ndev = NULL;
- g_monitor.mon_if[i].mon_ndev = NULL;
- g_monitor.count--;
+ if (g_monitor.monitor_state != MONITOR_STATE_DEINIT) {
+ for (i = 0; i < DHD_MAX_IFS; i++) {
+ ndev = g_monitor.mon_if[i].mon_ndev;
+ if (ndev) {
+ if (rtnl_is_locked()) {
+ rtnl_unlock();
+ rollback_lock = true;
+ }
+ unregister_netdev(ndev);
+ free_netdev(ndev);
+ g_monitor.mon_if[i].real_ndev = NULL;
+ g_monitor.mon_if[i].mon_ndev = NULL;
+ if (rollback_lock) {
+ rtnl_lock();
+ rollback_lock = false;
+ }
+ }
}
+ g_monitor.monitor_state = MONITOR_STATE_DEINIT;
}
-
mutex_unlock(&g_monitor.lock);
return 0;
}
diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c
index e57654b20e8..db763ab8c3d 100644
--- a/drivers/net/wireless/bcmdhd/dhd_sdio.c
+++ b/drivers/net/wireless/bcmdhd/dhd_sdio.c
@@ -395,7 +395,7 @@ static bool dhd_readahead;
(((uint8)(bus->tx_max - bus->tx_seq) > 1) && \
(((uint8)(bus->tx_max - bus->tx_seq) & 0x80) == 0))
-/* To check if there's window offered for ctrl frame*/
+/* To check if there's window offered for ctrl frame */
#define TXCTLOK(bus) \
(((uint8)(bus->tx_max - bus->tx_seq) != 0) && \
(((uint8)(bus->tx_max - bus->tx_seq) & 0x80) == 0))
@@ -4598,7 +4598,7 @@ clkwait:
framecnt = dhdsdio_sendfromq(bus, framecnt);
txlimit -= framecnt;
}
- /* Resched the DPC if ctrl cmd is pending on bus credit*/
+ /* Resched the DPC if ctrl cmd is pending on bus credit */
if (bus->ctrl_frame_stat)
resched = TRUE;
@@ -4958,6 +4958,14 @@ dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq)
}
#endif /* SDTEST */
+extern void
+dhd_disable_intr(dhd_pub_t *dhdp)
+{
+ dhd_bus_t *bus;
+ bus = dhdp->bus;
+ bcmsdh_intr_disable(bus->sdh);
+}
+
extern bool
dhd_bus_watchdog(dhd_pub_t *dhdp)
{
diff --git a/drivers/net/wireless/bcmdhd/include/epivers.h b/drivers/net/wireless/bcmdhd/include/epivers.h
index 3dfcc150301..5c63a391321 100644
--- a/drivers/net/wireless/bcmdhd/include/epivers.h
+++ b/drivers/net/wireless/bcmdhd/include/epivers.h
@@ -33,17 +33,17 @@
#define EPI_RC_NUMBER 125
-#define EPI_INCREMENTAL_NUMBER 48
+#define EPI_INCREMENTAL_NUMBER 52
#define EPI_BUILD_NUMBER 0
-#define EPI_VERSION 5, 90, 125, 48
+#define EPI_VERSION 5, 90, 125, 52
-#define EPI_VERSION_NUM 0x055a7d30
+#define EPI_VERSION_NUM 0x055a7d34
#define EPI_VERSION_DEV 5.90.125
-#define EPI_VERSION_STR "5.90.125.48"
+#define EPI_VERSION_STR "5.90.125.52"
#endif
diff --git a/drivers/net/wireless/bcmdhd/wl_android.c b/drivers/net/wireless/bcmdhd/wl_android.c
index 876fc080ac1..8314bbc5f44 100644
--- a/drivers/net/wireless/bcmdhd/wl_android.c
+++ b/drivers/net/wireless/bcmdhd/wl_android.c
@@ -92,7 +92,7 @@ typedef struct cmd_tlv {
char subver;
char reserved;
} cmd_tlv_t;
-#endif
+#endif /* PNO_SUPPORT */
typedef struct android_wifi_priv_cmd {
char *buf;
@@ -280,7 +280,7 @@ static int wl_android_set_pno_setup(struct net_device *dev, char *command, int t
exit_proc:
return res;
}
-#endif
+#endif /* PNO_SUPPORT */
static int wl_android_get_p2p_dev_addr(struct net_device *ndev, char *command, int total_len)
{
@@ -401,7 +401,7 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
if (!g_wifi_on) {
DHD_ERROR(("%s: Ignore private cmd \"%s\" - iface %s is down\n",
- __FUNCTION__, command, ifr->ifr_name));
+ __FUNCTION__, command, ifr->ifr_name));
ret = 0;
goto exit;
}
@@ -520,6 +520,17 @@ int wl_android_exit(void)
return ret;
}
+int wl_android_post_init(void)
+{
+ int ret = 0;
+ if (!dhd_download_fw_on_driverload) {
+ /* Call customer gpio to turn off power with WL_REG_ON signal */
+ dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
+ g_wifi_on = 0;
+
+ }
+ return ret;
+}
/**
* Functions for Android WiFi card detection
diff --git a/drivers/net/wireless/bcmdhd/wl_android.h b/drivers/net/wireless/bcmdhd/wl_android.h
index 3c75bfb820d..289a326fa33 100644
--- a/drivers/net/wireless/bcmdhd/wl_android.h
+++ b/drivers/net/wireless/bcmdhd/wl_android.h
@@ -22,7 +22,7 @@
*/
int wl_android_init(void);
int wl_android_exit(void);
-
+int wl_android_post_init(void);
int wl_android_wifi_on(struct net_device *dev);
int wl_android_wifi_off(struct net_device *dev);
int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd);
@@ -36,4 +36,4 @@ int wifi_get_irq_number(unsigned long *irq_flags_ptr);
int wifi_set_power(int on, unsigned long msec);
int wifi_get_mac_addr(unsigned char *buf);
void *wifi_get_country_code(char *ccode);
-#endif /* CONFIG_WIFI_CONTROL_FUNC */ \ No newline at end of file
+#endif /* CONFIG_WIFI_CONTROL_FUNC */
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index b7a8a7e5dde..b83cb3ee84e 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -138,28 +138,25 @@ static const struct ieee80211_regdomain brcm_regdom = {
/* IEEE 802.11b/g, channels 1..11 */
REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
/* IEEE 802.11b/g, channels 12..13. No HT40
- * channel fits here. */
+ * channel fits here.
+ */
REG_RULE(2467-10, 2472+10, 20, 6, 20,
- NL80211_RRF_PASSIVE_SCAN |
- NL80211_RRF_NO_IBSS),
+ NL80211_RRF_PASSIVE_SCAN |
+ NL80211_RRF_NO_IBSS),
/* IEEE 802.11 channel 14 - Only JP enables
- * this and for 802.11b only */
+ * this and for 802.11b only
+ */
REG_RULE(2484-10, 2484+10, 20, 6, 20,
- NL80211_RRF_PASSIVE_SCAN |
- NL80211_RRF_NO_IBSS |
- NL80211_RRF_NO_OFDM),
+ NL80211_RRF_PASSIVE_SCAN |
+ NL80211_RRF_NO_IBSS |
+ NL80211_RRF_NO_OFDM),
/* IEEE 802.11a, channel 36..48 */
- REG_RULE(5180-10, 5240+10, 40, 6, 20, 0
- /*NL80211_RRF_PASSIVE_SCAN |
- NL80211_RRF_NO_IBSS*/),
+ REG_RULE(5180-10, 5240+10, 40, 6, 20, 0),
/* NB: 5260 MHz - 5700 MHz requies DFS */
/* IEEE 802.11a, channel 149..165 */
- REG_RULE(5745-10, 5825+10, 40, 6, 20, 0
- /*NL80211_RRF_PASSIVE_SCAN |
- NL80211_RRF_NO_IBSS*/),
- }
+ REG_RULE(5745-10, 5825+10, 40, 6, 20, 0), }
};
@@ -170,8 +167,32 @@ static const struct ieee80211_regdomain brcm_regdom = {
#define WPS_ID_VERSION 0x104A
#define WPS_ID_DEVICE_PWD_ID 0x1012
#define WPS_ID_REQ_DEV_TYPE 0x106A
+#define WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS 0x1053
#define WPS_ID_PRIM_DEV_TYPE 0x1054
+/* Device Password ID */
+#define DEV_PW_DEFAULT 0x0000
+#define DEV_PW_USER_SPECIFIED 0x0001,
+#define DEV_PW_MACHINE_SPECIFIED 0x0002
+#define DEV_PW_REKEY 0x0003
+#define DEV_PW_PUSHBUTTON 0x0004
+#define DEV_PW_REGISTRAR_SPECIFIED 0x0005
+
+/* Config Methods */
+#define WPS_CONFIG_USBA 0x0001
+#define WPS_CONFIG_ETHERNET 0x0002
+#define WPS_CONFIG_LABEL 0x0004
+#define WPS_CONFIG_DISPLAY 0x0008
+#define WPS_CONFIG_EXT_NFC_TOKEN 0x0010
+#define WPS_CONFIG_INT_NFC_TOKEN 0x0020
+#define WPS_CONFIG_NFC_INTERFACE 0x0040
+#define WPS_CONFIG_PUSHBUTTON 0x0080
+#define WPS_CONFIG_KEYPAD 0x0100
+#define WPS_CONFIG_VIRT_PUSHBUTTON 0x0280
+#define WPS_CONFIG_PHY_PUSHBUTTON 0x0480
+#define WPS_CONFIG_VIRT_DISPLAY 0x2008
+#define WPS_CONFIG_PHY_DISPLAY 0x4008
+
/*
* cfg80211_ops api/callback list
*/
@@ -264,7 +285,6 @@ static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
const wl_event_msg_t *e, void *data);
static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
const wl_event_msg_t *e, void *data);
-
/*
* register/deregister sdio function
*/
@@ -455,6 +475,9 @@ static int wl_rfkill_set(void *data, bool blocked);
* Some external functions, TODO: move them to dhd_linux.h
*/
int dhd_add_monitor(char *name, struct net_device **new_ndev);
+int dhd_del_monitor(struct net_device *ndev);
+int dhd_monitor_init(void *dhd_pub);
+int dhd_monitor_uninit(void);
int dhd_start_xmit(struct sk_buff *skb, struct net_device *net);
#define WL_PRIV_GET() \
@@ -478,9 +501,11 @@ do { \
} \
} while (0)
+
#define IS_WPA_AKM(akm) ((akm) == RSN_AKM_NONE || \
- (akm) == RSN_AKM_UNSPECIFIED || \
- (akm) == RSN_AKM_PSK)
+ (akm) == RSN_AKM_UNSPECIFIED || \
+ (akm) == RSN_AKM_PSK)
+
extern int dhd_wait_pend8021x(struct net_device *dev);
@@ -762,7 +787,7 @@ static void swap_key_to_BE(struct wl_wsec_key *key)
/* For debug: Dump the contents of the encoded wps ie buffe */
static void
-wl_dbg_dump_wps_ie(char *wps_ie)
+wl_validate_wps_ie(char *wps_ie, bool *pbc)
{
#define WPS_IE_FIXED_LEN 6
u16 len = (u16) wps_ie[TLV_LEN_OFF];
@@ -808,6 +833,7 @@ wl_dbg_dump_wps_ie(char *wps_ie)
valptr[0] = *subel;
valptr[1] = *(subel + 1);
WL_DBG((" attr WPS_ID_DEVICE_PWD_ID: %u\n", HTON16(val)));
+ *pbc = (HTON16(val) == DEV_PW_PUSHBUTTON) ? true : false;
} else if (subelt_id == WPS_ID_PRIM_DEV_TYPE) {
valptr[0] = *subel;
valptr[1] = *(subel + 1);
@@ -822,6 +848,11 @@ wl_dbg_dump_wps_ie(char *wps_ie)
valptr[0] = *(subel + 6);
valptr[1] = *(subel + 7);
WL_DBG((" attr WPS_ID_REQ_DEV_TYPE: subcat=%u\n", HTON16(val)));
+ } else if (subelt_id == WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS) {
+ valptr[0] = *subel;
+ valptr[1] = *(subel + 1);
+ WL_DBG((" attr WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS"
+ ": cat=%u\n", HTON16(val)));
} else {
WL_DBG((" unknown attr 0x%x\n", subelt_id));
}
@@ -836,7 +867,7 @@ static struct net_device* wl_cfg80211_add_monitor_if(char *name)
struct net_device* ndev = NULL;
ret = dhd_add_monitor(name, &ndev);
- WL_ERR(("wl_cfg80211_add_monitor_if net device returned: 0x%p\n", ndev));
+ WL_INFO(("wl_cfg80211_add_monitor_if net device returned: 0x%p\n", ndev));
return ndev;
}
@@ -918,48 +949,48 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
strncpy(wl->p2p->vir_ifname, name, IFNAMSIZ - 1);
wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
- /* Temporary use channel 11, in case GO will be changed with set_channel API */
- chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN);
+ /* Temporary use channel 11, in case GO will be changed with set_channel API */
+ chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN);
- /* For P2P mode, use P2P-specific driver features to create the
- * bss: "wl p2p_ifadd"
- */
- wl_set_p2p_status(wl, IF_ADD);
+ /* For P2P mode, use P2P-specific driver features to create the
+ * bss: "wl p2p_ifadd"
+ */
+ wl_set_p2p_status(wl, IF_ADD);
err = wl_cfgp2p_ifadd(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec);
- if (unlikely(err))
- return ERR_PTR(-ENOMEM);
+ if (unlikely(err))
+ return ERR_PTR(-ENOMEM);
- timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
+ timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
(wl_get_p2p_status(wl, IF_ADD) == false),
- msecs_to_jiffies(MAX_WAIT_TIME));
- if (timeout > 0 && (!wl_get_p2p_status(wl, IF_ADD))) {
-
- struct wireless_dev *vwdev;
- vwdev = kzalloc(sizeof(*vwdev), GFP_KERNEL);
- if (unlikely(!vwdev)) {
- WL_ERR(("Could not allocate wireless device\n"));
- return ERR_PTR(-ENOMEM);
- }
- vwdev->wiphy = wl->wdev->wiphy;
+ msecs_to_jiffies(MAX_WAIT_TIME));
+ if (timeout > 0 && (!wl_get_p2p_status(wl, IF_ADD))) {
+
+ struct wireless_dev *vwdev;
+ vwdev = kzalloc(sizeof(*vwdev), GFP_KERNEL);
+ if (unlikely(!vwdev)) {
+ WL_ERR(("Could not allocate wireless device\n"));
+ return ERR_PTR(-ENOMEM);
+ }
+ vwdev->wiphy = wl->wdev->wiphy;
WL_INFO((" virtual interface(%s) is created \n", wl->p2p->vir_ifname));
- index = alloc_idx_vwdev(wl);
- wl->vwdev[index] = vwdev;
- vwdev->iftype =
- (wlif_type == WL_P2P_IF_CLIENT) ? NL80211_IFTYPE_STATION
- : NL80211_IFTYPE_AP;
- _ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
- _ndev->ieee80211_ptr = vwdev;
- SET_NETDEV_DEV(_ndev, wiphy_dev(vwdev->wiphy));
- vwdev->netdev = _ndev;
+ index = alloc_idx_vwdev(wl);
+ wl->vwdev[index] = vwdev;
+ vwdev->iftype =
+ (wlif_type == WL_P2P_IF_CLIENT) ? NL80211_IFTYPE_STATION
+ : NL80211_IFTYPE_AP;
+ _ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
+ _ndev->ieee80211_ptr = vwdev;
+ SET_NETDEV_DEV(_ndev, wiphy_dev(vwdev->wiphy));
+ vwdev->netdev = _ndev;
wl_set_drv_status(wl, READY);
wl->p2p->vif_created = true;
- set_mode_by_netdev(wl, _ndev, mode);
- wl = wdev_to_wl(vwdev);
- return _ndev;
+ set_mode_by_netdev(wl, _ndev, mode);
+ wl = wdev_to_wl(vwdev);
+ return _ndev;
- } else {
- wl_clr_p2p_status(wl, IF_ADD);
+ } else {
+ wl_clr_p2p_status(wl, IF_ADD);
WL_ERR((" virtual interface(%s) is not created \n", wl->p2p->vir_ifname));
memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ);
wl->p2p->vif_created = false;
@@ -975,7 +1006,11 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
struct ether_addr p2p_mac;
struct wl_priv *wl = WL_PRIV_GET();
s32 timeout = -1;
-
+ s32 ret = 0;
+ if (dev && dev->type == ARPHRD_IEEE80211_RADIOTAP) {
+ ret = dhd_del_monitor(dev);
+ goto exit;
+ }
if (wl->p2p_supported) {
memcpy(p2p_mac.octet, wl->p2p->int_addr.octet, ETHER_ADDR_LEN);
if (wl->p2p->vif_created) {
@@ -998,8 +1033,8 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
}
}
}
-
- return 0;
+exit:
+ return ret;
}
static s32
@@ -1137,7 +1172,7 @@ wl_cfg80211_notify_ifdel(struct net_device *net)
if (wl->p2p->vif_created) {
s32 index = 0;
- WL_DBG(("IF_DEL event called from dongle, _net name: %s, vif name: %s\n",
+ WL_DBG(("IF_DEL event called from dongle, _net name: %s, vif name: %s\n",
net->name, wl->p2p->vir_ifname));
memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ);
@@ -1155,10 +1190,10 @@ wl_cfg80211_notify_ifdel(struct net_device *net)
}
}
- wl_clr_p2p_status(wl, IF_DELETING);
+ wl_clr_p2p_status(wl, IF_DELETING);
/* Wake up any waiting thread */
- wake_up_interruptible(&wl->dongle_event_wait);
+ wake_up_interruptible(&wl->dongle_event_wait);
return 0;
}
@@ -2040,12 +2075,12 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
if (p2p_on(wl) && is_wps_conn(sme)) {
WL_DBG(("p2p index : %d\n", wl_cfgp2p_find_idx(wl, dev)));
/* Have to apply WPS IE + P2P IE in assoc req frame */
- wl_cfgp2p_set_managment_ie(wl, dev,
+ wl_cfgp2p_set_management_ie(wl, dev,
wl_cfgp2p_find_idx(wl, dev), VNDR_IE_PRBREQ_FLAG,
wl_to_p2p_bss_saved_ie(wl, P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie,
wl_to_p2p_bss_saved_ie(wl,
P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len);
- wl_cfgp2p_set_managment_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev),
+ wl_cfgp2p_set_management_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev),
VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
} else if (p2p_on(wl) && (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
/* This is the connect req after WPS is done [credentials exchanged]
@@ -2054,7 +2089,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
* the newly received IEs from Supplicant. This will remove the WPS IE from
* the Assoc Req.
*/
- wl_cfgp2p_set_managment_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev),
+ wl_cfgp2p_set_management_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev),
VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
}
@@ -3040,9 +3075,9 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
}
if (wl->p2p_supported && p2p_on(wl)) {
wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
- /* Suspend P2P discovery search-listen to prevent it from changing the
- * channel.
- */
+ /* Suspend P2P discovery search-listen to prevent it from changing the
+ * channel.
+ */
if ((err = wl_cfgp2p_discover_enable_search(wl, false)) < 0) {
WL_ERR(("Can not disable discovery mode\n"));
return -EFAULT;
@@ -3076,17 +3111,15 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
*/
wpsie_len = wps_ie->length + sizeof(wps_ie->length) +
sizeof(wps_ie->tag);
- wl_cfgp2p_set_managment_ie(wl, dev, bssidx,
+ wl_cfgp2p_set_management_ie(wl, dev, bssidx,
VNDR_IE_PRBRSP_FLAG,
(u8 *)wps_ie, wpsie_len + p2pie_len);
/* remove WLC_E_PROBREQ_MSG event to prevent HOSTAPD
* from responding many probe request
*/
- wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, false);
}
}
cfg80211_mgmt_tx_status(dev, *cookie, buf, len, true, GFP_KERNEL);
-
goto exit;
} else {
/* Abort the dwell time of any previous off-channel action frame that may
@@ -3484,6 +3517,7 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
wifi_p2p_ie_t *p2p_ie;
bool is_bssup = false;
bool update_bss = false;
+ bool pbc = false;
u16 wpsie_len = 0;
u16 p2pie_len = 0;
u8 beacon_ie[IE_MAX_LEN];
@@ -3521,8 +3555,7 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
/*
* Should be compared with saved ie before saving it
*/
- if (wl_dbg_level & WL_DBG_INFO)
- wl_dbg_dump_wps_ie((char *) wps_ie);
+ wl_validate_wps_ie((char *) wps_ie, &pbc);
memcpy(beacon_ie, wps_ie, wpsie_len);
} else {
WL_ERR(("No WPSIE in beacon \n"));
@@ -3544,9 +3577,9 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
} else {
WL_ERR(("No P2PIE in beacon \n"));
}
- wl_cfgp2p_set_managment_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
+ wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
beacon_ie, wpsie_len + p2pie_len);
- wl_cfgp2p_set_managment_ie(wl, dev, bssidx, VNDR_IE_ASSOCRSP_FLAG,
+ wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_ASSOCRSP_FLAG,
beacon_ie, wpsie_len + p2pie_len);
/* find the RSN_IE */
@@ -3634,16 +3667,15 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
/*
* Should be compared with saved ie before saving it
*/
- if (wl_dbg_level & WL_DBG_INFO)
- wl_dbg_dump_wps_ie((char *) wps_ie);
+ wl_validate_wps_ie((char *) wps_ie, &pbc);
memcpy(beacon_ie, wps_ie, wpsie_len);
- wl_cfgp2p_set_managment_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
+ wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
beacon_ie, wpsie_len);
wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
/* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
- wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, true);
+ wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
} else {
- WL_ERR(("No WPSIE in beacon \n"));
+ WL_DBG(("No WPSIE in beacon \n"));
}
wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), false);
@@ -3667,10 +3699,9 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
/*
* Should be compared with saved ie before saving it
*/
- if (wl_dbg_level & WL_DBG_INFO)
- wl_dbg_dump_wps_ie((char *) wps_ie);
+ wl_validate_wps_ie((char *) wps_ie, &pbc);
memcpy(beacon_ie, wps_ie, wpsie_len);
- wl_cfgp2p_set_managment_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
+ wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
beacon_ie, wpsie_len);
if (wl->ap_info->wps_ie &&
memcmp(wl->ap_info->wps_ie, wps_ie, wpsie_len)) {
@@ -3678,12 +3709,12 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
kfree(wl->ap_info->wps_ie);
wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
/* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
- wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, true);
+ wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
} else if (wl->ap_info->wps_ie == NULL) {
WL_DBG((" WPS IE is added\n"));
wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
/* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
- wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, true);
+ wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
}
/* find the RSN_IE */
if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
@@ -5050,7 +5081,7 @@ static void wl_notify_escan_complete(struct wl_priv *wl, bool aborted)
}
wl_clr_drv_status(wl, SCANNING);
if (wl->p2p_supported && p2p_on(wl))
- wl_clr_p2p_status(wl, SCANNING);
+ wl_clr_p2p_status(wl, SCANNING);
if (likely(wl->scan_request)) {
cfg80211_scan_done(wl->scan_request, aborted);
@@ -5085,7 +5116,6 @@ static s32 wl_escan_handler(struct wl_priv *wl,
WL_ERR(("Invalid escan result (NULL pointer)\n"));
goto exit;
}
-
if (dtoh16(escan_result->bss_count) != 1) {
WL_ERR(("Invalid bss_count %d: ignoring\n", escan_result->bss_count));
goto exit;
@@ -6034,7 +6064,7 @@ static s32 __wl_cfg80211_up(struct wl_priv *wl)
err = wl_config_dongle(wl, false);
if (unlikely(err))
return err;
-
+ dhd_monitor_init(wl->pub);
wl_invoke_iscan(wl);
wl_set_drv_status(wl, READY);
return err;
@@ -6071,6 +6101,7 @@ static s32 __wl_cfg80211_down(struct wl_priv *wl)
wl_link_down(wl);
if (wl->p2p_supported)
wl_cfgp2p_down(wl);
+ dhd_monitor_uninit();
wl_debugfs_remove_netdev(wl);
@@ -6107,7 +6138,6 @@ s32 wl_cfg80211_down(void)
return err;
}
-
static s32 wl_dongle_probecap(struct wl_priv *wl)
{
s32 err = 0;
@@ -6420,6 +6450,7 @@ s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pd
static __used void wl_dongle_poweron(struct wl_priv *wl)
{
+
WL_DBG(("Enter \n"));
dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON);
@@ -6434,6 +6465,8 @@ static __used void wl_dongle_poweron(struct wl_priv *wl)
static __used void wl_dongle_poweroff(struct wl_priv *wl)
{
+
+
WL_DBG(("Enter \n"));
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
wl_cfg80211_suspend(wl_to_wiphy(wl), NULL);
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
index fa88d4b4cf8..7a5619e8ec4 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
@@ -21,11 +21,9 @@
* 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,v 1.1.4.1.2.14 2011-02-09 01:40:07 Exp $
- * $Id$
+ * $Id: wl_cfgp2p.c,v 1.1.4.1.2.14 2011-02-09 01:40:07 Exp $
+ *
*/
-
-
#include <typedefs.h>
#include <linuxver.h>
#include <osl.h>
@@ -436,7 +434,7 @@ wl_cfgp2p_enable_discovery(struct wl_priv *wl, struct net_device *dev, const u8
CFGP2P_ERR((" wsec error %d\n", ret));
}
set_ie:
- ret = wl_cfgp2p_set_managment_ie(wl, dev,
+ ret = wl_cfgp2p_set_management_ie(wl, dev,
wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE),
VNDR_IE_PRBREQ_FLAG, ie, ie_len);
@@ -604,7 +602,7 @@ wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active,
*/
s32
-wl_cfgp2p_set_managment_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx,
+wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx,
s32 pktflag, const u8 *vndr_ie, u32 vndr_ie_len)
{
/* Vendor-specific Information Element ID */
@@ -677,7 +675,7 @@ wl_cfgp2p_set_managment_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssi
}
/* Add if there is any extra IE */
if (vndr_ie && vndr_ie_len) {
- CFGP2P_ERR(("Request has extra IE"));
+ CFGP2P_INFO(("Request has extra IE"));
if (vndr_ie_len > mgmt_ie_buf_len) {
CFGP2P_ERR(("extra IE size too big\n"));
ret = -ENOMEM;
@@ -898,7 +896,7 @@ wl_cfgp2p_find_idx(struct wl_priv *wl, struct net_device *ndev)
return P2PAPI_BSSCFG_PRIMARY;
}
for (i = 0; i < P2PAPI_BSSCFG_MAX; i++) {
- if (ndev == wl_to_p2p_bss_ndev(wl, i)) {
+ if (ndev == wl_to_p2p_bss_ndev(wl, i)) {
index = wl_to_p2p_bss_bssidx(wl, i);
break;
}
@@ -1015,11 +1013,11 @@ wl_cfgp2p_discover_enable_search(struct wl_priv *wl, u8 enable)
CFGP2P_DBG((" Enter\n"));
if (!wl_get_p2p_status(wl, DISCOVERY_ON)) {
- CFGP2P_ERR((" do nothing, discovery is off\n"));
+ CFGP2P_DBG((" do nothing, discovery is off\n"));
return ret;
}
if (wl_get_p2p_status(wl, SEARCH_ENABLED) == enable) {
- CFGP2P_ERR(("already : %d\n", enable));
+ CFGP2P_DBG(("already : %d\n", enable));
return ret;
}
@@ -1254,7 +1252,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 error %d\n", ret));
return 0;
}
if (p2p_supported == 1) {
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h b/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
index 1b28fa9b80a..971633ae214 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
+++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.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,v 1.1.4.1.2.8 2011/02/09 01:37:52 Exp $
+ * $Id: wl_cfgp2p.h,v 1.1.4.1.2.8 2011/02/09 01:37:52 Exp $
*/
#ifndef _wl_cfgp2p_h_
#define _wl_cfgp2p_h_
@@ -176,7 +176,7 @@ extern wifi_p2p_ie_t *
wl_cfgp2p_find_p2pie(u8 *parse, u32 len);
extern s32
-wl_cfgp2p_set_managment_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx,
+wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx,
s32 pktflag, const u8 *vndr_ie, u32 vndr_ie_len);
extern s32
wl_cfgp2p_clear_management_ie(struct wl_priv *wl, s32 bssidx);