diff options
author | Howard M. Harte <hharte@broadcom.com> | 2010-07-27 18:50:25 -0700 |
---|---|---|
committer | Howard M. Harte <hharte@broadcom.com> | 2010-07-27 18:50:25 -0700 |
commit | 45762b7e0c8813c6f27963d1f557f517aeab8369 (patch) | |
tree | 808c97bbb00f8e1952b62529cbd1a5bf44b323b1 | |
parent | dd0ed55b6892078730078b3b971d2768954891c4 (diff) | |
download | broadcom-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.c | 497 | ||||
-rw-r--r-- | bcm4329/src/wl/sys/wl_iw.h | 20 |
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(¶ms->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); |