aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/bcmdhd/wl_iw.c
diff options
context:
space:
mode:
authorHoward M. Harte <hharte@broadcom.com>2011-08-29 19:01:55 -0700
committerDmitry Shmidt <dimitrysh@google.com>2011-08-31 10:24:25 -0700
commite2ed1e7561b284588471fc8a80e931e51d6b38a8 (patch)
tree9eeee952c4ed84eed66ee0172c3c82bc1ce563f1 /drivers/net/wireless/bcmdhd/wl_iw.c
parentc71b5e2bf3cd6757618a1e36c402620646dc0967 (diff)
downloadkernel_samsung_crespo-e2ed1e7561b284588471fc8a80e931e51d6b38a8.zip
kernel_samsung_crespo-e2ed1e7561b284588471fc8a80e931e51d6b38a8.tar.gz
kernel_samsung_crespo-e2ed1e7561b284588471fc8a80e931e51d6b38a8.tar.bz2
net: wireless: bcmdhd: Update to 5.90.125.74
Change-Id: I427ee7a07e794b228e58fa2edbaa127481b67398 Signed-off-by: Howard M. Harte <hharte@broadcom.com> Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'drivers/net/wireless/bcmdhd/wl_iw.c')
-rw-r--r--drivers/net/wireless/bcmdhd/wl_iw.c141
1 files changed, 140 insertions, 1 deletions
diff --git a/drivers/net/wireless/bcmdhd/wl_iw.c b/drivers/net/wireless/bcmdhd/wl_iw.c
index 6d546fc..f74115c 100644
--- a/drivers/net/wireless/bcmdhd/wl_iw.c
+++ b/drivers/net/wireless/bcmdhd/wl_iw.c
@@ -179,6 +179,11 @@ static wlc_ssid_t g_specific_ssid;
static wlc_ssid_t g_ssid;
+#ifdef CONFIG_WPS2
+static char *g_wps_probe_req_ie;
+static int g_wps_probe_req_ie_len;
+#endif
+
bool btcoex_is_sco_active(struct net_device *dev);
static wl_iw_ss_cache_ctrl_t g_ss_cache_ctrl;
#if defined(CONFIG_FIRST_SCAN)
@@ -6242,6 +6247,118 @@ exit_proc:
#endif
+#ifdef CONFIG_WPS2
+static int
+wl_iw_del_wps_probe_req_ie(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra
+)
+{
+ int ret;
+ vndr_ie_setbuf_t *ie_delbuf;
+
+ if (g_wps_probe_req_ie) {
+ ie_delbuf = (vndr_ie_setbuf_t *)(g_wps_probe_req_ie + strlen("vndr_ie "));
+ strncpy(ie_delbuf->cmd, "del", 3);
+ ie_delbuf->cmd[3] = '\0';
+
+ ret = dev_wlc_ioctl(dev, WLC_SET_VAR, g_wps_probe_req_ie, g_wps_probe_req_ie_len);
+ if (ret) {
+ WL_ERROR(("ioctl failed %d \n", ret));
+ }
+
+ kfree(g_wps_probe_req_ie);
+ g_wps_probe_req_ie = NULL;
+ g_wps_probe_req_ie_len = 0;
+ }
+
+ return 0;
+}
+
+static int
+wl_iw_add_wps_probe_req_ie(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra
+)
+{
+ char *str_ptr = NULL;
+ char *bufptr = NULL;
+ uint buflen, datalen, iecount, pktflag, iolen, total_len;
+ int ret = 0;
+ vndr_ie_setbuf_t *ie_setbuf = NULL;
+
+ if (!g_wps_probe_req_ie) {
+ ret = -1;
+ str_ptr = extra;
+ str_ptr += WPS_PROBE_REQ_IE_CMD_LENGTH;
+ datalen = wrqu->data.length - WPS_PROBE_REQ_IE_CMD_LENGTH;
+
+ buflen = sizeof(vndr_ie_setbuf_t) + datalen - sizeof(vndr_ie_t);
+ ie_setbuf = (vndr_ie_setbuf_t *)kmalloc(buflen, GFP_KERNEL);
+ if (!ie_setbuf) {
+ WL_ERROR(("memory alloc failure ie_setbuf\n"));
+ return ret;
+ }
+
+ memset(ie_setbuf, 0x00, buflen);
+
+ strncpy(ie_setbuf->cmd, "add", VNDR_IE_CMD_LEN - 1);
+ ie_setbuf->cmd[VNDR_IE_CMD_LEN - 1] = '\0';
+
+ iecount = htod32(1);
+ memcpy((void *)&ie_setbuf->vndr_ie_buffer.iecount, &iecount, sizeof(int));
+
+ pktflag = 0x10;
+ memcpy((void *)&ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].pktflag, &pktflag, sizeof(uint32));
+
+ memcpy((void *)&ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data, str_ptr, datalen);
+
+ total_len = strlen("vndr_ie ") + buflen;
+ bufptr = (char *)kmalloc(total_len, GFP_KERNEL);
+ if (!bufptr) {
+ WL_ERROR(("memory alloc failure bufptr\n"));
+ goto fail;
+ }
+
+ iolen = bcm_mkiovar("vndr_ie", (char *)ie_setbuf, buflen, bufptr, total_len);
+ if (iolen == 0) {
+ WL_ERROR(("Buffer length is illegal\n"));
+ goto fail2;
+ }
+
+ ret = dev_wlc_ioctl(dev, WLC_SET_VAR, bufptr, iolen);
+ if (ret) {
+ WL_ERROR(("ioctl failed\n"));
+ goto fail2;
+ }
+
+ g_wps_probe_req_ie = (char *)kmalloc(iolen, GFP_KERNEL);
+ if (!g_wps_probe_req_ie) {
+ WL_ERROR(("memory alloc failure g_wps_probe_req_ie\n"));
+ goto fail2;
+ }
+
+ memcpy(g_wps_probe_req_ie, bufptr, iolen);
+ g_wps_probe_req_ie_len = iolen;
+ }
+
+fail2:
+ if (bufptr) {
+ kfree(bufptr);
+ bufptr = NULL;
+ }
+fail:
+ if (ie_setbuf) {
+ kfree(ie_setbuf);
+ ie_setbuf = NULL;
+ }
+ return ret;
+}
+#endif
#ifdef SOFTAP
@@ -6345,11 +6462,14 @@ get_softap_auto_channel(struct net_device *dev, struct ap_profile *ap)
return res;
}
#endif
+
memset(&null_ssid, 0, sizeof(wlc_ssid_t));
res |= dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown));
+
#ifdef AP_ONLY
res |= dev_wlc_ioctl(dev, WLC_SET_SSID, &null_ssid, sizeof(null_ssid));
#else
+
iolen = wl_bssiovar_mkbuf("ssid", bsscfg_index, (char *)(&null_ssid),
null_ssid.SSID_len+4, buf, sizeof(buf), &mkvar_err);
ASSERT(iolen);
@@ -6660,6 +6780,7 @@ wl_iw_set_ap_security(struct net_device *dev, struct ap_profile *ap)
WL_SOFTAP((" channel = %d\n", ap->channel));
WL_SOFTAP((" max scb = %d\n", ap->max_scb));
+
if (strnicmp(ap->sec, "open", strlen("open")) == 0) {
@@ -7406,6 +7527,12 @@ wl_iw_set_priv(
else if (strnicmp(extra, CSCAN_COMMAND, strlen(CSCAN_COMMAND)) == 0)
ret = wl_iw_set_cscan(dev, info, (union iwreq_data *)dwrq, extra);
#endif
+#ifdef CONFIG_WPS2
+ else if (strnicmp(extra, WPS_ADD_PROBE_REQ_IE_CMD, strlen(WPS_ADD_PROBE_REQ_IE_CMD)) == 0)
+ ret = wl_iw_add_wps_probe_req_ie(dev, info, (union iwreq_data *)dwrq, extra);
+ else if (strnicmp(extra, WPS_DEL_PROBE_REQ_IE_CMD, strlen(WPS_DEL_PROBE_REQ_IE_CMD)) == 0)
+ ret = wl_iw_del_wps_probe_req_ie(dev, info, (union iwreq_data *)dwrq, extra);
+#endif
else if (strnicmp(extra, "POWERMODE", strlen("POWERMODE")) == 0)
ret = wl_iw_set_power_mode(dev, info, (union iwreq_data *)dwrq, extra);
else if (strnicmp(extra, "BTCOEXMODE", strlen("BTCOEXMODE")) == 0)
@@ -7420,7 +7547,7 @@ wl_iw_set_priv(
WL_SOFTAP(("penguin, set AP_MAC_LIST_SET\n"));
set_ap_mac_list(dev, (extra + PROFILE_OFFSET));
}
-#endif
+#endif
else {
WL_ERROR(("Unknown PRIVATE command %s - ignored\n", extra));
snprintf(extra, MAX_WX_STRING, "OK");
@@ -8546,6 +8673,10 @@ wl_iw_attach(struct net_device *dev, void * dhdp)
g_iscan->scan_flag = 0;
#endif
+#ifdef CONFIG_WPS2
+ g_wps_probe_req_ie = NULL;
+ g_wps_probe_req_ie_len = 0;
+#endif
iscan->timer_ms = 8000;
init_timer(&iscan->timer);
@@ -8613,6 +8744,14 @@ wl_iw_detach(void)
kfree(g_scan);
g_scan = NULL;
+#ifdef CONFIG_WPS2
+
+ if (g_wps_probe_req_ie) {
+ kfree(g_wps_probe_req_ie);
+ g_wps_probe_req_ie = NULL;
+ g_wps_probe_req_ie_len = 0;
+ }
+#endif
#if !defined(CSCAN)
wl_iw_release_ss_cache_ctrl();
#endif