summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHoward M. Harte <hharte@broadcom.com>2010-07-27 18:50:25 -0700
committerHoward M. Harte <hharte@broadcom.com>2010-07-27 18:50:25 -0700
commit45762b7e0c8813c6f27963d1f557f517aeab8369 (patch)
tree808c97bbb00f8e1952b62529cbd1a5bf44b323b1
parentdd0ed55b6892078730078b3b971d2768954891c4 (diff)
downloadbroadcom-45762b7e0c8813c6f27963d1f557f517aeab8369.tar.gz
Fix ISCAN params when scaning again from Partial
WL_SCAN_ACTION_CONTINUE. Change-Id: Ib91b190358d3fbcc2927a5dcd17ffb3069bb1aff
-rw-r--r--bcm4329/src/wl/sys/wl_iw.c497
-rw-r--r--bcm4329/src/wl/sys/wl_iw.h20
2 files changed, 340 insertions, 177 deletions
diff --git a/bcm4329/src/wl/sys/wl_iw.c b/bcm4329/src/wl/sys/wl_iw.c
index ec52705..d817dcc 100644
--- a/bcm4329/src/wl/sys/wl_iw.c
+++ b/bcm4329/src/wl/sys/wl_iw.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_iw.c,v 1.51.4.9.2.6.4.116 2010/07/08 00:51:57 Exp $
+ * $Id: wl_iw.c,v 1.51.4.9.2.6.4.124 2010/07/27 20:46:02 Exp $
*/
#include <wlioctl.h>
@@ -54,6 +54,7 @@ typedef const struct si_pub si_t;
#define WL_ASSOC(x)
#define WL_INFORM(x)
#define WL_WSEC(x)
+#define WL_SCAN(x)
#include <wl_iw.h>
@@ -217,7 +218,9 @@ typedef struct iscan_info {
#else
char ioctlbuf[WLC_IOCTL_SMLEN];
#endif
-
+
+ wl_iscan_params_t *iscan_ex_params_p;
+ int iscan_ex_param_size;
} iscan_info_t;
#define COEX_DHCP 1
static void wl_iw_bt_flag_set(struct net_device *dev, bool set);
@@ -314,7 +317,7 @@ dev_wlc_ioctl(
struct ifreq ifr;
wl_ioctl_t ioc;
mm_segment_t fs;
- int ret = -1;
+ int ret = -EINVAL;
if (!dev) {
WL_ERROR(("%s: dev is null\n", __FUNCTION__));
@@ -323,26 +326,35 @@ dev_wlc_ioctl(
WL_INFORM(("\n%s, PID:%x: send Local IOCTL -> dhd: cmd:0x%x, buf:%p, len:%d ,\n",
__FUNCTION__, current->pid, cmd, arg, len));
- memset(&ioc, 0, sizeof(ioc));
- ioc.cmd = cmd;
- ioc.buf = arg;
- ioc.len = len;
- strcpy(ifr.ifr_name, dev->name);
- ifr.ifr_data = (caddr_t) &ioc;
+ if (g_onoff == G_WLAN_SET_ON) {
+ memset(&ioc, 0, sizeof(ioc));
+ ioc.cmd = cmd;
+ ioc.buf = arg;
+ ioc.len = len;
-
- dev_open(dev);
+ strcpy(ifr.ifr_name, dev->name);
+ ifr.ifr_data = (caddr_t) &ioc;
+
+
+ ret = dev_open(dev);
+ if (ret) {
+ WL_ERROR(("%s: Error dev_open: %d\n", __func__, ret));
+ return ret;
+ }
- fs = get_fs();
- set_fs(get_ds());
+ fs = get_fs();
+ set_fs(get_ds());
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
- ret = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
+ ret = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
#else
- ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
+ ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
#endif
- set_fs(fs);
-
+ set_fs(fs);
+ }
+ else {
+ WL_TRACE(("%s: call after driver stop : ignored\n", __FUNCTION__));
+ }
return ret;
}
@@ -877,6 +889,69 @@ wl_iw_get_link_speed(
return error;
}
+
+static int
+wl_iw_get_band(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra
+)
+{
+ int error = -1;
+ char *p = extra;
+ static int band;
+
+ if (g_onoff == G_WLAN_SET_ON) {
+ error = dev_wlc_ioctl(dev, WLC_GET_BAND, &band, sizeof(band));
+
+ p += snprintf(p, MAX_WX_STRING, "Band %d", band);
+
+ wrqu->data.length = p - extra + 1;
+ }
+ return error;
+}
+
+
+static int
+wl_iw_set_band(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra
+)
+{
+ int error = -1;
+ char *p = extra;
+ char band;
+
+ if (g_onoff == G_WLAN_SET_ON) {
+
+ band = *(extra + strlen(BAND_SET_CMD) + 1) - '0';
+
+ if ((band == WLC_BAND_AUTO) || (band == WLC_BAND_5G) || (band == WLC_BAND_2G)) {
+
+
+ if ((error = dev_wlc_ioctl(dev, WLC_SET_BAND,
+ &band, sizeof(band))) >= 0) {
+ p += snprintf(p, MAX_WX_STRING, "OK");
+ WL_TRACE(("%s: set band %d OK\n", __FUNCTION__, band));
+ goto exit;
+ }
+ else WL_ERROR(("%s: set band %d failed code %d\n", __FUNCTION__, \
+ band, error));
+ }
+ else WL_ERROR(("%s Incorrect band setting, ignored\n", __FUNCTION__));
+ }
+
+ p += snprintf(p, MAX_WX_STRING, "FAIL");
+
+exit:
+ wrqu->data.length = p - extra + 1;
+ return error;
+}
+
+
static int
wl_iw_get_rssi(
struct net_device *dev,
@@ -1482,6 +1557,7 @@ wl_iw_set_freq(
chan = wf_mhz2channel(fwrq->m, sf);
}
chan = htod32(chan);
+
if ((error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan))))
return error;
@@ -2130,33 +2206,23 @@ wl_iw_iscan_prep(wl_scan_params_t *params, wlc_ssid_t *ssid)
static int
wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action)
{
- int params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params));
- wl_iscan_params_t *params;
int err = 0;
- if (ssid && ssid->SSID_len) {
- params_size += sizeof(wlc_ssid_t);
- }
- params = (wl_iscan_params_t*)kmalloc(params_size, GFP_KERNEL);
- if (params == NULL) {
- return -ENOMEM;
- }
- memset(params, 0, params_size);
- ASSERT(params_size < sizeof(iscan->ioctlbuf));
-
- err = wl_iw_iscan_prep(&params->params, ssid);
+ iscan->iscan_ex_params_p->version = htod32(ISCAN_REQ_VERSION);
+ iscan->iscan_ex_params_p->action = htod16(action);
+ iscan->iscan_ex_params_p->scan_duration = htod16(0);
- if (!err) {
- params->version = htod32(ISCAN_REQ_VERSION);
- params->action = htod16(action);
- params->scan_duration = htod16(0);
+ WL_SCAN(("%s : nprobes=%d\n", __FUNCTION__, iscan->iscan_ex_params_p->params.nprobes));
+ WL_SCAN(("active_time=%d\n", iscan->iscan_ex_params_p->params.active_time));
+ WL_SCAN(("passive_time=%d\n", iscan->iscan_ex_params_p->params.passive_time));
+ WL_SCAN(("home_time=%d\n", iscan->iscan_ex_params_p->params.home_time));
+ WL_SCAN(("scan_type=%d\n", iscan->iscan_ex_params_p->params.scan_type));
+ WL_SCAN(("bss_type=%d\n", iscan->iscan_ex_params_p->params.bss_type));
-
- (void) dev_iw_iovar_setbuf(iscan->dev, "iscan", params, params_size,
- iscan->ioctlbuf, sizeof(iscan->ioctlbuf));
- }
+
+ (void) dev_iw_iovar_setbuf(iscan->dev, "iscan", iscan->iscan_ex_params_p, \
+ iscan->iscan_ex_param_size, iscan->ioctlbuf, sizeof(iscan->ioctlbuf));
- kfree(params);
return err;
}
@@ -2718,12 +2784,6 @@ wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag)
}
#endif
-
- memset(&ssid, 0, sizeof(ssid));
-
- iscan->list_cur = iscan->list_hdr;
- iscan->iscan_state = ISCAN_STATE_SCANING;
-
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
if (flag)
rtnl_lock();
@@ -2733,7 +2793,14 @@ wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag)
wl_iw_set_event_mask(dev);
WL_TRACE(("+++: Set Broadcast ISCAN\n"));
+
+ memset(&ssid, 0, sizeof(ssid));
+
+ iscan->list_cur = iscan->list_hdr;
+ iscan->iscan_state = ISCAN_STATE_SCANING;
+ memset(&iscan->iscan_ex_params_p->params, 0, iscan->iscan_ex_param_size);
+ wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, &ssid);
wl_iw_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
@@ -4858,6 +4925,7 @@ int dev_iw_read_cfg1_bss_var(struct net_device *dev, int *val)
+#ifndef AP_ONLY
static int wl_bssiovar_mkbuf(
const char *iovar,
int bssidx,
@@ -4905,6 +4973,7 @@ static int wl_bssiovar_mkbuf(
*perr = 0;
return iolen;
}
+#endif
@@ -4933,8 +5002,7 @@ int get_user_params(char *user_params, struct iw_point *dwrq)
static int
-wl_iw_combined_scan_set(struct net_device *dev, wl_iscan_params_t *iscan_params, \
- wlc_ssid_t* ssids_local, int nssid, int nchan)
+wl_iw_combined_scan_set(struct net_device *dev, wlc_ssid_t* ssids_local, int nssid, int nchan)
{
int params_size = WL_SCAN_PARAMS_FIXED_SIZE + WL_NUMCHANNELS * sizeof(uint16);
int err = 0;
@@ -4942,9 +5010,9 @@ wl_iw_combined_scan_set(struct net_device *dev, wl_iscan_params_t *iscan_params,
int i;
iscan_info_t *iscan = g_iscan;
- WL_TRACE(("%s nssid=%d nchan=%d\n", __FUNCTION__, nssid, nchan));
+ WL_ERROR(("%s nssid=%d nchan=%d\n", __FUNCTION__, nssid, nchan));
- if ((!dev) && (!g_iscan) && (!iscan_params)) {
+ if ((!dev) && (!g_iscan) && (!iscan->iscan_ex_params_p)) {
WL_ERROR(("%s error exit\n", __FUNCTION__));
err = -1;
}
@@ -4961,19 +5029,25 @@ wl_iw_combined_scan_set(struct net_device *dev, wl_iscan_params_t *iscan_params,
goto exit;
}
- p = ((char*)&iscan_params->params) + i;
+ p = ((char*)&iscan->iscan_ex_params_p->params) + i;
memcpy(p, ssids_local, nssid * sizeof(wlc_ssid_t));
p += nssid * sizeof(wlc_ssid_t);
} else {
- p = (char*)iscan_params->params.channel_list + nchan * sizeof(uint16);
+ p = (char*)iscan->iscan_ex_params_p->params.channel_list + nchan * sizeof(uint16);
}
- iscan_params->params.channel_num = htod32((nssid << WL_SCAN_PARAMS_NSSID_SHIFT) | \
+ iscan->iscan_ex_params_p->params.channel_num = \
+ htod32((nssid << WL_SCAN_PARAMS_NSSID_SHIFT) | \
(nchan & WL_SCAN_PARAMS_COUNT_MASK));
+ nssid = \
+ (uint)((iscan->iscan_ex_params_p->params.channel_num >> WL_SCAN_PARAMS_NSSID_SHIFT) & \
+ WL_SCAN_PARAMS_COUNT_MASK);
+
- params_size = (int) (p - (char*)iscan_params + nssid * sizeof(wlc_ssid_t));
+ params_size = (int) (p - (char*)iscan->iscan_ex_params_p + nssid * sizeof(wlc_ssid_t));
+ iscan->iscan_ex_param_size = params_size;
iscan->list_cur = iscan->list_hdr;
iscan->iscan_state = ISCAN_STATE_SCANING;
@@ -4982,26 +5056,29 @@ wl_iw_combined_scan_set(struct net_device *dev, wl_iscan_params_t *iscan_params,
iscan->timer_on = 1;
-#define SCAN_DUMP 1
#ifdef SCAN_DUMP
- printf("\n### List of SSIDs to scan ###\n");
- for (i = 0; i < nssid; i++) {
- if (!ssids_local[i].SSID_len)
- printf("%d: Broadcast scan\n", i);
- else
- printf("%d: scan for %s size =%d\n", i, \
- ssids_local[i].SSID, ssids_local[i].SSID_len);
- }
- printf("### List of channels to scan ###\n");
- for (i = 0; i < nchan; i++)
{
- printf("%d ", iscan_params->params.channel_list[i]);
+ int i;
+ WL_SCAN(("\n### List of SSIDs to scan ###\n"));
+ for (i = 0; i < nssid; i++) {
+ if (!ssids_local[i].SSID_len)
+ WL_SCAN(("%d: Broadcast scan\n", i));
+ else
+ WL_SCAN(("%d: scan for %s size =%d\n", i, \
+ ssids_local[i].SSID, ssids_local[i].SSID_len));
+ }
+ WL_SCAN(("### List of channels to scan ###\n"));
+ for (i = 0; i < nchan; i++)
+ {
+ WL_SCAN(("%d ", iscan->iscan_ex_params_p->params.channel_list[i]));
+ }
+ WL_SCAN(("\nnprobes=%d\n", iscan->iscan_ex_params_p->params.nprobes));
+ WL_SCAN(("active_time=%d\n", iscan->iscan_ex_params_p->params.active_time));
+ WL_SCAN(("passive_time=%d\n", iscan->iscan_ex_params_p->params.passive_time));
+ WL_SCAN(("home_time=%d\n", iscan->iscan_ex_params_p->params.home_time));
+ WL_SCAN(("scan_type=%d\n", iscan->iscan_ex_params_p->params.scan_type));
+ WL_SCAN(("\n###################\n"));
}
- printf("\nnprobes=%d\n", iscan_params->params.nprobes);
- printf("active_time=%d\n", iscan_params->params.active_time);
- printf("passive_time=%d\n", iscan_params->params.passive_time);
- printf("home_time=%d\n", iscan_params->params.home_time);
- printf("\n###################\n");
#endif
if (params_size > WLC_IOCTL_MEDLEN) {
@@ -5010,7 +5087,8 @@ wl_iw_combined_scan_set(struct net_device *dev, wl_iscan_params_t *iscan_params,
err = -1;
}
- if ((err = dev_iw_iovar_setbuf(dev, "iscan", iscan_params, params_size, \
+ if ((err = dev_iw_iovar_setbuf(dev, "iscan", iscan->iscan_ex_params_p, \
+ iscan->iscan_ex_param_size, \
iscan->ioctlbuf, sizeof(iscan->ioctlbuf)))) {
WL_TRACE(("Set ISCAN for %s failed with %d\n", __FUNCTION__, err));
err = -1;
@@ -5027,14 +5105,11 @@ static int iwpriv_set_cscan(struct net_device *dev, struct iw_request_info *info
{
int res = 0;
char *extra = NULL;
- int params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params)) +
- (WL_NUMCHANNELS * sizeof(uint16));
- wl_iscan_params_t *iscan_params;
+ iscan_info_t *iscan = g_iscan;
wlc_ssid_t ssids_local[WL_SCAN_PARAMS_SSID_MAX];
int nssid = 0;
int nchan = 0;
-
WL_TRACE(("\%s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n",
__FUNCTION__, info->cmd, info->flags,
wrqu->data.pointer, wrqu->data.length));
@@ -5048,6 +5123,10 @@ static int iwpriv_set_cscan(struct net_device *dev, struct iw_request_info *info
char *str_ptr;
+ if (!iscan->iscan_ex_params_p) {
+ return -EFAULT;
+ }
+
if (!(extra = kmalloc(wrqu->data.length+1, GFP_KERNEL)))
return -ENOMEM;
@@ -5074,51 +5153,43 @@ static int iwpriv_set_cscan(struct net_device *dev, struct iw_request_info *info
return -1;
}
-
- params_size += WL_SCAN_PARAMS_SSID_MAX * sizeof(wlc_ssid_t);
-
- iscan_params = (wl_iscan_params_t*)kmalloc(params_size, GFP_KERNEL);
- if (iscan_params == NULL) {
- WL_ERROR(("%s Failed allocate %d bytes \n", __FUNCTION__, params_size));
- return -ENOMEM;
- }
-
- memset(iscan_params, 0, params_size);
- ASSERT(params_size < WLC_IOCTL_MAXLEN);
+ memset(iscan->iscan_ex_params_p, 0, iscan->iscan_ex_param_size);
+ ASSERT(iscan->iscan_ex_param_size < WLC_IOCTL_MAXLEN);
- iscan_params->version = htod32(ISCAN_REQ_VERSION);
- iscan_params->action = htod16(WL_SCAN_ACTION_START);
- iscan_params->scan_duration = htod16(0);
-
- wl_iw_iscan_prep(&iscan_params->params, NULL);
+ wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, NULL);
+ iscan->iscan_ex_params_p->version = htod32(ISCAN_REQ_VERSION);
+ iscan->iscan_ex_params_p->action = htod16(WL_SCAN_ACTION_START);
+ iscan->iscan_ex_params_p->scan_duration = htod16(0);
if ((nchan = wl_iw_parse_channel_list(&str_ptr, \
- &iscan_params->params.channel_list[0], \
- WL_NUMCHANNELS)) == -1) {
+ &iscan->iscan_ex_params_p->params.channel_list[0], \
+ WL_NUMCHANNELS)) == -1) {
WL_ERROR(("%s missing channel list\n", __FUNCTION__));
return -1;
}
get_parmeter_from_string(&str_ptr, \
- GET_NPROBE, PTYPE_INTDEC, &iscan_params->params.nprobes, 2);
+ GET_NPROBE, PTYPE_INTDEC, \
+ &iscan->iscan_ex_params_p->params.nprobes, 2);
get_parmeter_from_string(&str_ptr, GET_ACTIVE_ASSOC_DWELL, PTYPE_INTDEC, \
- &iscan_params->params.active_time, 3);
+ &iscan->iscan_ex_params_p->params.active_time, 4);
get_parmeter_from_string(&str_ptr, GET_PASSIVE_ASSOC_DWELL, PTYPE_INTDEC, \
- &iscan_params->params.passive_time, 3);
+ &iscan->iscan_ex_params_p->params.passive_time, 4);
get_parmeter_from_string(&str_ptr, GET_HOME_DWELL, PTYPE_INTDEC, \
- &iscan_params->params.home_time, 3);
+ &iscan->iscan_ex_params_p->params.home_time, 4);
+
+ get_parmeter_from_string(&str_ptr, GET_SCAN_TYPE, PTYPE_INTDEC, \
+ &iscan->iscan_ex_params_p->params.scan_type, 1);
- res = wl_iw_combined_scan_set(dev, iscan_params, \
- ssids_local, nssid, nchan);
+ res = wl_iw_combined_scan_set(dev, ssids_local, nssid, nchan);
- kfree(iscan_params);
} else {
WL_ERROR(("IWPRIV argument len = 0 \n"));
@@ -5142,9 +5213,7 @@ wl_iw_set_cscan(
)
{
int res = -1;
- int params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params)) + \
- (WL_NUMCHANNELS * sizeof(uint16));
- wl_iscan_params_t *iscan_params;
+ iscan_info_t *iscan = g_iscan;
wlc_ssid_t ssids_local[WL_SCAN_PARAMS_SSID_MAX];
int nssid = 0;
int nchan = 0;
@@ -5156,15 +5225,20 @@ wl_iw_set_cscan(
int i;
char tlv_in_example[] = { 'C', 'S', 'C', 'A', 'N', ' ', \
0x53, 0x01, 0x00, 0x00,
- 0x01,
+ 'S',
0x00,
- 0x01,
+ 'S',
0x04,
'B', 'R', 'C', 'M',
- 0x02,
- 0x00
+ 'C',
+ 0x06,
+ 'P',
+ 0x94,
+ 0x11,
+ 'T',
+ 0x01
};
-#endif
+#endif
WL_TRACE(("\n### %s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n",
__FUNCTION__, info->cmd, info->flags,
@@ -5175,7 +5249,6 @@ wl_iw_set_cscan(
return -1;
}
-
if (wrqu->data.length < (strlen(CSCAN_COMMAND) + sizeof(cscan_tlv_t))) {
WL_ERROR(("%s aggument=%d less %d\n", __FUNCTION__, \
wrqu->data.length, strlen(CSCAN_COMMAND) + sizeof(cscan_tlv_t)));
@@ -5212,22 +5285,13 @@ wl_iw_set_cscan(
}
else {
- params_size += WL_SCAN_PARAMS_SSID_MAX * sizeof(wlc_ssid_t);
-
- iscan_params = (wl_iscan_params_t*)kmalloc(params_size, GFP_KERNEL);
- if (iscan_params == NULL) {
- WL_ERROR(("%s Failed allocate %d bytes \n", \
- __FUNCTION__, params_size));
- return -ENOMEM;
- }
- memset(iscan_params, 0, params_size);
- ASSERT(params_size < WLC_IOCTL_MAXLEN);
+ memset(iscan->iscan_ex_params_p, 0, iscan->iscan_ex_param_size);
- iscan_params->version = htod32(ISCAN_REQ_VERSION);
- iscan_params->action = htod16(WL_SCAN_ACTION_START);
- iscan_params->scan_duration = htod16(0);
- wl_iw_iscan_prep(&iscan_params->params, NULL);
+ wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, NULL);
+ iscan->iscan_ex_params_p->version = htod32(ISCAN_REQ_VERSION);
+ iscan->iscan_ex_params_p->action = htod16(WL_SCAN_ACTION_START);
+ iscan->iscan_ex_params_p->scan_duration = htod16(0);
while (tlv_size_left > 0)
@@ -5237,68 +5301,68 @@ wl_iw_set_cscan(
case CSCAN_TLV_TYPE_CHANNEL_IE:
if ((nchan = wl_iw_parse_channel_list_tlv(&str_ptr, \
- &iscan_params->params.channel_list[0], \
+ &iscan->iscan_ex_params_p->params.channel_list[0], \
WL_NUMCHANNELS, &tlv_size_left)) == -1) {
WL_ERROR(("%s missing channel list\n", \
__FUNCTION__));
- goto exit_scan;
+ goto exit_proc;
}
break;
case CSCAN_TLV_TYPE_NPROBE_IE:
if ((res = wl_iw_parse_data_tlv(&str_ptr, \
- &iscan_params->params.nprobes, \
- sizeof(iscan_params->params.nprobes), \
+ &iscan->iscan_ex_params_p->params.nprobes, \
+ sizeof(iscan->iscan_ex_params_p->params.nprobes), \
type, sizeof(char), &tlv_size_left)) == -1) {
WL_ERROR(("%s return %d\n", \
__FUNCTION__, res));
- goto exit_scan;
+ goto exit_proc;
}
break;
case CSCAN_TLV_TYPE_ACTIVE_IE:
if ((res = wl_iw_parse_data_tlv(&str_ptr, \
- &iscan_params->params.active_time, \
- sizeof(iscan_params->params.active_time), \
- type, sizeof(short), &tlv_size_left)) == -1) {
- WL_ERROR(("%s return %d\n", \
- __FUNCTION__, res));
- goto exit_scan;
+ &iscan->iscan_ex_params_p->params.active_time, \
+ sizeof(iscan->iscan_ex_params_p->params.active_time), \
+ type, sizeof(short), &tlv_size_left)) == -1) {
+ WL_ERROR(("%s return %d\n", \
+ __FUNCTION__, res));
+ goto exit_proc;
}
break;
case CSCAN_TLV_TYPE_PASSIVE_IE:
if ((res = wl_iw_parse_data_tlv(&str_ptr, \
- &iscan_params->params.passive_time, \
- sizeof(iscan_params->params.passive_time), \
- type, sizeof(short), &tlv_size_left)) == -1) {
- WL_ERROR(("%s return %d\n", \
- __FUNCTION__, res));
- goto exit_scan;
- }
+ &iscan->iscan_ex_params_p->params.passive_time, \
+ sizeof(iscan->iscan_ex_params_p->params.passive_time), \
+ type, sizeof(short), &tlv_size_left)) == -1) {
+ WL_ERROR(("%s return %d\n", \
+ __FUNCTION__, res));
+ goto exit_proc;
+ }
break;
case CSCAN_TLV_TYPE_HOME_IE:
if ((res = wl_iw_parse_data_tlv(&str_ptr, \
- &iscan_params->params.home_time, \
- sizeof(iscan_params->params.home_time), \
- type, sizeof(short), &tlv_size_left)) == -1) {
- WL_ERROR(("%s return %d\n", \
- __FUNCTION__, res));
- goto exit_scan;
- }
+ &iscan->iscan_ex_params_p->params.home_time, \
+ sizeof(iscan->iscan_ex_params_p->params.home_time), \
+ type, sizeof(short), &tlv_size_left)) == -1) {
+ WL_ERROR(("%s return %d\n", \
+ __FUNCTION__, res));
+ goto exit_proc;
+ }
break;
case CSCAN_TLV_TYPE_STYPE_IE:
if ((res = wl_iw_parse_data_tlv(&str_ptr, \
- &iscan_params->params.scan_type, \
- sizeof(iscan_params->params.scan_type), \
- type, sizeof(char), &tlv_size_left)) == -1) {
- WL_ERROR(("%s return %d\n", \
- __FUNCTION__, res));
- goto exit_scan;
- }
+ &iscan->iscan_ex_params_p->params.scan_type, \
+ sizeof(iscan->iscan_ex_params_p->params.scan_type), \
+ type, sizeof(char), &tlv_size_left)) == -1) {
+ WL_ERROR(("%s return %d\n", \
+ __FUNCTION__, res));
+ goto exit_proc;
+ }
break;
default :
WL_ERROR(("%s get unkwown type %X\n", \
__FUNCTION__, type));
- goto exit_scan;
+ goto exit_proc;
break;
}
}
@@ -5310,14 +5374,9 @@ wl_iw_set_cscan(
}
- res = wl_iw_combined_scan_set(dev, iscan_params, \
- ssids_local, nssid, nchan);
-
-exit_scan:
- kfree(iscan_params);
+ res = wl_iw_combined_scan_set(dev, ssids_local, nssid, nchan);
exit_proc:
-
return res;
}
@@ -5326,6 +5385,7 @@ exit_proc:
#ifdef SOFTAP
+#ifndef AP_ONLY
static int thr_wait_for_2nd_eth_dev(void *data)
@@ -5364,7 +5424,10 @@ fail:
return ret;
}
-
+#endif
+#ifndef AP_ONLY
+static int last_auto_channel = 6;
+#endif
static int get_softap_auto_channel(struct net_device *dev, struct ap_profile *ap)
{
int chosen = 0;
@@ -5375,19 +5438,30 @@ static int get_softap_auto_channel(struct net_device *dev, struct ap_profile *ap
int ret = 0;
wlc_ssid_t null_ssid;
int res = 0;
+#ifndef AP_ONLY
int iolen = 0;
int mkvar_err = 0;
int bsscfg_index = 1;
char buf[WLC_IOCTL_SMLEN];
-
+#endif
WL_SOFTAP(("Enter %s\n", __FUNCTION__));
+
+#ifndef AP_ONLY
+ if (ap_cfg_running) {
+ ap->channel = last_auto_channel;
+ 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);
res |= dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen);
-
+#endif
auto_channel_retry:
request.count = htod32(0);
ret = dev_wlc_ioctl(dev, WLC_START_CHANNEL_SEL, &request, sizeof(request));
@@ -5417,6 +5491,11 @@ static int get_softap_auto_channel(struct net_device *dev, struct ap_profile *ap
WL_ERROR(("%s fail to set up err =%d\n", __FUNCTION__, res));
goto fail;
}
+#ifndef AP_ONLY
+ if (!res)
+ last_auto_channel = ap->channel;
+#endif
+
fail :
return res;
}
@@ -5429,14 +5508,16 @@ static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap)
wlc_ssid_t ap_ssid;
int max_assoc = 8;
- int mpc = 0;
int res = 0;
int apsta_var = 0;
+#ifndef AP_ONLY
+ int mpc = 0;
int iolen = 0;
int mkvar_err = 0;
int bsscfg_index = 1;
char buf[WLC_IOCTL_SMLEN];
+#endif
wl_iw_t *iw;
if (!dev) {
@@ -5457,9 +5538,18 @@ static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap)
WAKE_LOCK_INIT(iw->pub, WAKE_LOCK_SOFTAP_SET, "SoftAP_SET");
WAKE_LOCK(iw->pub, WAKE_LOCK_SOFTAP_SET);
+#ifdef AP_ONLY
+ if (ap_cfg_running) {
+ wl_iw_softap_deassoc_stations(dev);
+ ap_cfg_running = FALSE;
+ }
+#endif
+
if (ap_cfg_running == FALSE) {
+#ifndef AP_ONLY
+
sema_init(&ap_eth_sema, 0);
@@ -5468,6 +5558,7 @@ static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap)
WL_ERROR(("%s fail to set mpc\n", __FUNCTION__));
goto fail;
}
+#endif
updown = 0;
if ((res = dev_wlc_ioctl(dev, WLC_DOWN, &updown, sizeof(updown)))) {
@@ -5556,6 +5647,16 @@ static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap)
strncpy(ap_ssid.SSID, ap->ssid, ap_ssid.SSID_len);
+#ifdef AP_ONLY
+ if ((res = wl_iw_set_ap_security(dev, &my_ap)) != 0) {
+ WL_ERROR(("ERROR:%d in:%s, wl_iw_set_ap_security is skipped\n", \
+ res, __FUNCTION__));
+ goto fail;
+ }
+ wl_iw_send_priv_event(dev, "ASCII_CMD=AP_BSS_START");
+ ap_cfg_running = TRUE;
+#else
+
iolen = wl_bssiovar_mkbuf("ssid", bsscfg_index, (char *)(&ap_ssid),
ap_ssid.SSID_len+4, buf, sizeof(buf), &mkvar_err);
ASSERT(iolen);
@@ -5590,6 +5691,7 @@ static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap)
goto fail;
}
}
+#endif
fail:
WAKE_UNLOCK(iw->pub, WAKE_LOCK_SOFTAP_SET);
WAKE_LOCK_DESTROY(iw->pub, WAKE_LOCK_SOFTAP_SET);
@@ -5609,6 +5711,11 @@ static int wl_iw_set_ap_security(struct net_device *dev, struct ap_profile *ap)
int res = 0;
int i;
char *ptr;
+#ifdef AP_ONLY
+ int mpc = 0;
+ wlc_ssid_t ap_ssid;
+#endif
+ wl_wsec_key_t key;
WL_SOFTAP(("\nsetting SOFTAP security mode:\n"));
WL_SOFTAP(("wl_iw: set ap profile:\n"));
@@ -5635,7 +5742,6 @@ static int wl_iw_set_ap_security(struct net_device *dev, struct ap_profile *ap)
} else if (strnicmp(ap->sec, "wep", strlen("wep")) == 0) {
- wl_wsec_key_t key;
memset(&key, 0, sizeof(key));
wsec = WEP_ENABLED;
@@ -5761,6 +5867,16 @@ static int wl_iw_set_ap_security(struct net_device *dev, struct ap_profile *ap)
WL_SOFTAP((" wsec & auth set 'wpa-psk' (TKIP), result:&d %d\n", res));
}
+#ifdef AP_ONLY
+ ap_ssid.SSID_len = strlen(ap->ssid);
+ strncpy(ap_ssid.SSID, ap->ssid, ap_ssid.SSID_len);
+ res |= dev_wlc_ioctl(dev, WLC_SET_SSID, &ap_ssid, sizeof(ap_ssid));
+ mpc = 0;
+ res |= dev_wlc_intvar_set(dev, "mpc", mpc);
+ if (strnicmp(ap->sec, "wep", strlen("wep")) == 0) {
+ res |= dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+ }
+#endif
return res;
}
@@ -5906,10 +6022,14 @@ static int iwpriv_softap_stop(struct net_device *dev,
WAKE_LOCK(iw->pub, WAKE_LOCK_SOFTAP_STOP);
if ((ap_cfg_running == TRUE)) {
+#ifdef AP_ONLY
+ wl_iw_softap_deassoc_stations(dev);
+#else
wl_iw_softap_deassoc_stations(ap_net_dev);
if ((res = dev_iw_write_cfg1_bss_var(dev, 2)) < 0)
WL_ERROR(("%s failed to del BSS err = %d", __FUNCTION__, res));
+#endif
bcm_mdelay(100);
@@ -6049,6 +6169,7 @@ static int
WAKE_LOCK(iw->pub, WAKE_LOCK_SOFTAP_START);
+#ifndef AP_ONLY
if ((res = wl_iw_set_ap_security(dev, &my_ap)) != 0) {
WL_ERROR((" %s ERROR setting SOFTAP security in :%d\n", __FUNCTION__, res));
}
@@ -6061,6 +6182,8 @@ static int
bcm_mdelay(100);
}
+#endif
+
WL_SOFTAP(("%s done with res %d \n", __FUNCTION__, res));
WAKE_UNLOCK(iw->pub, WAKE_LOCK_SOFTAP_START);
WAKE_LOCK_DESTROY(iw->pub, WAKE_LOCK_SOFTAP_START);
@@ -6200,6 +6323,7 @@ int wl_iw_process_private_ascii_cmd(
WL_SOFTAP(("\n!!! got 'WL_AP_EN_BSS' from WPA supplicant, dev:%s\n", dev->name));
+#ifndef AP_ONLY
if (ap_net_dev == NULL) {
printf("\n ERROR: SOFTAP net_dev* is NULL !!!\n");
} else {
@@ -6208,7 +6332,11 @@ int wl_iw_process_private_ascii_cmd(
WL_ERROR(("%s line %d fail to set bss up\n", \
__FUNCTION__, __LINE__));
}
-
+#else
+ if ((ret = iwpriv_en_ap_bss(dev, info, dwrq, cmd_str)) < 0)
+ WL_ERROR(("%s line %d fail to set bss up\n", \
+ __FUNCTION__, __LINE__));
+#endif
} else if (strnicmp(sub_cmd, "ASSOC_LST", strlen("ASSOC_LST")) == 0) {
@@ -6216,10 +6344,12 @@ int wl_iw_process_private_ascii_cmd(
} else if (strnicmp(sub_cmd, "AP_BSS_STOP", strlen("AP_BSS_STOP")) == 0) {
WL_SOFTAP((" \n temp DOWN SOFTAP\n"));
+#ifndef AP_ONLY
if ((ret = dev_iw_write_cfg1_bss_var(dev, 0)) < 0) {
WL_ERROR(("%s line %d fail to set bss down\n", \
__FUNCTION__, __LINE__));
}
+#endif
}
return ret;
@@ -6290,6 +6420,10 @@ static int wl_iw_set_priv(
ret = wl_iw_set_country(dev, info, (union iwreq_data *)dwrq, extra);
else if (strnicmp(extra, "STOP", strlen("STOP")) == 0)
ret = wl_iw_control_wl_off(dev, info);
+ else if (strnicmp(extra, BAND_GET_CMD, strlen(BAND_GET_CMD)) == 0)
+ ret = wl_iw_get_band(dev, info, (union iwreq_data *)dwrq, extra);
+ else if (strnicmp(extra, BAND_SET_CMD, strlen(BAND_SET_CMD)) == 0)
+ ret = wl_iw_set_band(dev, info, (union iwreq_data *)dwrq, extra);
#if defined(CSCAN)
else if (strnicmp(extra, CSCAN_COMMAND, strlen(CSCAN_COMMAND)) == 0)
@@ -6907,7 +7041,11 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
#ifdef SOFTAP
+#ifdef AP_ONLY
+ if (ap_cfg_running) {
+#else
if (ap_cfg_running && !strncmp(dev->name, "wl0.1", 5)) {
+#endif
WL_SOFTAP(("AP DOWN %d\n", event_type));
wl_iw_send_priv_event(priv_dev, "AP_DOWN");
@@ -6917,7 +7055,7 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
}
#else
g_ss_cache_ctrl.m_link_down = 1;
-#endif
+#endif
WL_TRACE(("Link Down\n"));
bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN);
@@ -6932,7 +7070,11 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
memcpy(g_ss_cache_ctrl.m_active_bssid, &e->addr, ETHER_ADDR_LEN);
#ifdef SOFTAP
+#ifdef AP_ONLY
+ if (ap_cfg_running) {
+#else
if (ap_cfg_running && !strncmp(dev->name, "wl0.1", 5)) {
+#endif
WL_SOFTAP(("AP UP %d\n", event_type));
wl_iw_send_priv_event(priv_dev, "AP_UP");
@@ -7289,6 +7431,7 @@ wl_iw_bt_init(struct net_device *dev)
int wl_iw_attach(struct net_device *dev, void * dhdp)
{
+ int params_size;
wl_iw_t *iw;
#if defined(WL_IW_USE_ISCAN)
iscan_info_t *iscan = NULL;
@@ -7296,15 +7439,30 @@ int wl_iw_attach(struct net_device *dev, void * dhdp)
if (!dev)
return 0;
+
+#ifdef CSCAN
+ params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params)) +
+ (WL_NUMCHANNELS * sizeof(uint16)) + WL_SCAN_PARAMS_SSID_MAX * sizeof(wlc_ssid_t);
+#else
+ params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params));
+#endif
iscan = kmalloc(sizeof(iscan_info_t), GFP_KERNEL);
+
if (!iscan)
return -ENOMEM;
memset(iscan, 0, sizeof(iscan_info_t));
+
+
+ iscan->iscan_ex_params_p = (wl_iscan_params_t*)kmalloc(params_size, GFP_KERNEL);
+ if (!iscan->iscan_ex_params_p)
+ return -ENOMEM;
+ iscan->iscan_ex_param_size = params_size;
iscan->sysioc_pid = -1;
g_iscan = iscan;
iscan->dev = dev;
iscan->iscan_state = ISCAN_STATE_IDLE;
+
g_first_broadcast_scan = BROADCAST_SCAN_FIRST_IDLE;
g_iscan->scan_flag = 0;
@@ -7369,6 +7527,7 @@ void wl_iw_detach(void)
iscan->list_hdr = buf;
}
MUTEX_UNLOCK_WL_SCAN_SET();
+ kfree(iscan->iscan_ex_params_p);
kfree(iscan);
g_iscan = NULL;
#endif
diff --git a/bcm4329/src/wl/sys/wl_iw.h b/bcm4329/src/wl/sys/wl_iw.h
index 0b7ece1..6375e94 100644
--- a/bcm4329/src/wl/sys/wl_iw.h
+++ b/bcm4329/src/wl/sys/wl_iw.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_iw.h,v 1.5.34.1.6.21 2010/07/08 00:50:58 Exp $
+ * $Id: wl_iw.h,v 1.5.34.1.6.24 2010/07/27 20:46:02 Exp $
*/
@@ -41,6 +41,10 @@
#define GET_ACTIVE_ASSOC_DWELL "ACTIVE="
#define GET_PASSIVE_ASSOC_DWELL "PASSIVE="
#define GET_HOME_DWELL "HOME="
+#define GET_SCAN_TYPE "TYPE="
+
+#define BAND_GET_CMD "BANDGET"
+#define BAND_SET_CMD "BANDSET"
#define SOFTAP 1
@@ -199,13 +203,13 @@ typedef struct cscan_tlv {
#define CSCAN_TLV_PREFIX 'S'
#define CSCAN_TLV_VERSION 1
#define CSCAN_TLV_SUBVERSION 0
-#define CSCAN_TLV_TYPE_SSID_IE 1
-#define CSCAN_TLV_TYPE_CHANNEL_IE 2
-#define CSCAN_TLV_TYPE_NPROBE_IE 3
-#define CSCAN_TLV_TYPE_ACTIVE_IE 4
-#define CSCAN_TLV_TYPE_PASSIVE_IE 5
-#define CSCAN_TLV_TYPE_HOME_IE 6
-#define CSCAN_TLV_TYPE_STYPE_IE 7
+#define CSCAN_TLV_TYPE_SSID_IE 'S'
+#define CSCAN_TLV_TYPE_CHANNEL_IE 'C'
+#define CSCAN_TLV_TYPE_NPROBE_IE 'N'
+#define CSCAN_TLV_TYPE_ACTIVE_IE 'A'
+#define CSCAN_TLV_TYPE_PASSIVE_IE 'P'
+#define CSCAN_TLV_TYPE_HOME_IE 'H'
+#define CSCAN_TLV_TYPE_STYPE_IE 'T'
extern int wl_iw_parse_channel_list_tlv(char** list_str, uint16* channel_list, \
int channel_num, int *bytes_left);