diff options
author | Dmitry Shmidt <dimitrysh@google.com> | 2010-03-29 16:16:26 -0700 |
---|---|---|
committer | Dmitry Shmidt <dimitrysh@google.com> | 2010-03-29 16:16:26 -0700 |
commit | ce8b788a61ad48e60fb6fe182facd2297b97db9b (patch) | |
tree | c3d67040ca6bdb82b9dcdecbd6df24485f816de8 | |
parent | 1a9040ebea203168187d4e8f55cd5566a8eace4c (diff) | |
download | wlan-ce8b788a61ad48e60fb6fe182facd2297b97db9b.tar.gz |
bcm4329: Sync with kernel SHA1: e3e6e272c600d7fa3d8722351129b04b0697e608
Change-Id: I1bef51c1ccfafd7822267523833e710ca17e022d
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
-rw-r--r-- | bcm4329/src/dhd/sys/dhd_linux.c | 27 | ||||
-rw-r--r-- | bcm4329/src/include/epivers.h | 10 | ||||
-rw-r--r-- | bcm4329/src/wl/sys/wl_iw.c | 148 |
3 files changed, 136 insertions, 49 deletions
diff --git a/bcm4329/src/dhd/sys/dhd_linux.c b/bcm4329/src/dhd/sys/dhd_linux.c index ef529e7..ec211ac 100644 --- a/bcm4329/src/dhd/sys/dhd_linux.c +++ b/bcm4329/src/dhd/sys/dhd_linux.c @@ -22,7 +22,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd_linux.c,v 1.65.4.9.2.12.2.60 2010/02/23 00:18:36 Exp $ + * $Id: dhd_linux.c,v 1.65.4.9.2.12.2.60.4.4 2010/03/25 05:07:49 Exp $ */ #ifdef CONFIG_WIFI_CONTROL_FUNC @@ -812,8 +812,30 @@ _dhd_sysioc_thread(void *data) dhd_os_wake_lock(&dhd->pub); for (i = 0; i < DHD_MAX_IFS; i++) { if (dhd->iflist[i]) { +#ifdef SOFTAP + bool in_ap = (ap_net_dev != NULL); +#endif /* SOFTAP */ + if (dhd->iflist[i]->state) dhd_op_if(dhd->iflist[i]); + +#ifdef SOFTAP + if (dhd->iflist[i] == NULL) { + DHD_TRACE(("%s: interface %d just been removed!\n\n", __FUNCTION__, i)); + continue; + } + + if (in_ap && dhd->set_macaddress) { + DHD_TRACE(("attempt to set MAC for %s in AP Mode blocked.\n", dhd->iflist[i]->net->name)); + dhd->set_multicast = FALSE; + continue; + } else if (in_ap && dhd->set_multicast) { + DHD_TRACE(("attempt to set MULTICAST list for %s in AP Mode blocked.\n", dhd->iflist[i]->net->name)); + dhd->set_macaddress = FALSE; + continue; + } +#endif /* SOFTAP */ + if (dhd->set_multicast) { dhd->set_multicast = FALSE; _dhd_set_multicast_list(dhd, i); @@ -916,7 +938,8 @@ dhd_start_xmit(struct sk_buff *skb, struct net_device *net) /* Reject if down */ if (!dhd->pub.up || (dhd->pub.busstate == DHD_BUS_DOWN)) { - DHD_ERROR(("%s: xmit rejected due to dhd bus down status \n", __FUNCTION__)); + DHD_ERROR(("%s: xmit rejected pub.up=%d busstate=%d\n", + __FUNCTION__, dhd->pub.up, dhd->pub.busstate)); netif_stop_queue(net); return -ENODEV; } diff --git a/bcm4329/src/include/epivers.h b/bcm4329/src/include/epivers.h index 8137f60..4957e1a 100644 --- a/bcm4329/src/include/epivers.h +++ b/bcm4329/src/include/epivers.h @@ -33,16 +33,16 @@ #define EPI_RC_NUMBER 204 -#define EPI_INCREMENTAL_NUMBER 1 +#define EPI_INCREMENTAL_NUMBER 3 #define EPI_BUILD_NUMBER 0 -#define EPI_VERSION 4, 218, 204, 1 +#define EPI_VERSION 4, 218, 204, 3 -#define EPI_VERSION_NUM 0x04dacc01 +#define EPI_VERSION_NUM 0x04dacc03 -#define EPI_VERSION_STR "4.218.204.1" -#define EPI_ROUTER_VERSION_STR "4.219.204.1" +#define EPI_VERSION_STR "4.218.204.3" +#define EPI_ROUTER_VERSION_STR "4.219.204.3" #endif diff --git a/bcm4329/src/wl/sys/wl_iw.c b/bcm4329/src/wl/sys/wl_iw.c index e324dd3..f44fba9 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.84.2.3 2010/03/16 22:09:45 Exp $ + * $Id: wl_iw.c,v 1.51.4.9.2.6.4.84.2.10 2010/03/25 07:22:21 Exp $ */ @@ -77,6 +77,7 @@ static int ap_mode = 0; static int g_onoff = G_WLAN_SET_ON; static struct mutex wl_start_lock; +static struct mutex wl_cache_lock; extern bool wl_iw_conn_status_str(uint32 event_type, uint32 status, uint32 reason, char* stringBuf, uint buflen); @@ -1875,7 +1876,6 @@ wl_iw_get_aplist( if (!extra) return -EINVAL; - list = kmalloc(buflen, GFP_KERNEL); if (!list) return -ENOMEM; @@ -1929,7 +1929,6 @@ wl_iw_get_aplist( dwrq->flags = 1; } - return 0; } @@ -2004,7 +2003,6 @@ wl_iw_iscan_get_aplist( dwrq->flags = 1; } - return 0; } @@ -2101,7 +2099,7 @@ wl_iw_iscan_get(iscan_info_t *iscan) wl_scan_results_t *results; uint32 status; - + mutex_lock(&wl_cache_lock); if (iscan->list_cur) { buf = iscan->list_cur; iscan->list_cur = buf->next; @@ -2111,6 +2109,7 @@ wl_iw_iscan_get(iscan_info_t *iscan) if (!buf) { WL_ERROR(("%s can't alloc iscan_buf_t : going to abort currect iscan\n", \ __FUNCTION__)); + mutex_unlock(&wl_cache_lock); return WL_SCAN_RESULTS_NO_MEM; } buf->next = NULL; @@ -2147,6 +2146,7 @@ wl_iw_iscan_get(iscan_info_t *iscan) WL_TRACE(("results->buflen = %d\n", results->buflen)); status = dtoh32(list_buf->status); + mutex_unlock(&wl_cache_lock); return status; } @@ -2312,6 +2312,7 @@ wl_iw_free_ss_cache(void) WL_TRACE(("%s called\n", __FUNCTION__)); + mutex_lock(&wl_cache_lock); spec_scan_head = &g_ss_cache_ctrl.m_cache_head; node = *spec_scan_head; @@ -2322,6 +2323,7 @@ wl_iw_free_ss_cache(void) kfree(cur); } *spec_scan_head = NULL; + mutex_unlock(&wl_cache_lock); } @@ -2367,6 +2369,7 @@ wl_iw_reset_ss_cache(void) wl_iw_ss_cache_t *node, *prev, *cur; wl_iw_ss_cache_t **spec_scan_head; + mutex_lock(&wl_cache_lock); spec_scan_head = &g_ss_cache_ctrl.m_cache_head; node = *spec_scan_head; prev = node; @@ -2393,7 +2396,7 @@ wl_iw_reset_ss_cache(void) prev = node; node = node->next; } - + mutex_unlock(&wl_cache_lock); } @@ -2406,13 +2409,13 @@ wl_iw_add_bss_to_ss_cache(wl_scan_results_t *ss_list) wl_bss_info_t *bi = NULL; int i; - spec_scan_head = &g_ss_cache_ctrl.m_cache_head; - if (!ss_list->count) { return 0; } - + mutex_lock(&wl_cache_lock); + spec_scan_head = &g_ss_cache_ctrl.m_cache_head; + for (i = 0; i < ss_list->count; i++) { node = *spec_scan_head; @@ -2437,6 +2440,7 @@ wl_iw_add_bss_to_ss_cache(wl_scan_results_t *ss_list) } leaf = kmalloc(WLC_IW_SS_CACHE_MAXLEN, GFP_KERNEL); if (!leaf) { + mutex_unlock(&wl_cache_lock); return -ENOMEM; } @@ -2459,8 +2463,8 @@ wl_iw_add_bss_to_ss_cache(wl_scan_results_t *ss_list) prev->next = leaf; } } + mutex_unlock(&wl_cache_lock); return 0; - } @@ -2471,6 +2475,7 @@ __u16 *merged_len) wl_iw_ss_cache_t *node; wl_scan_results_t *list_merge; + mutex_lock(&wl_cache_lock); node = g_ss_cache_ctrl.m_cache_head; for (;node;) { list_merge = (wl_scan_results_t *)node; @@ -2485,6 +2490,7 @@ __u16 *merged_len) } node = node->next; } + mutex_unlock(&wl_cache_lock); return 0; } @@ -2496,6 +2502,7 @@ wl_iw_delete_bss_from_ss_cache(void *addr) wl_iw_ss_cache_t *node, *prev; wl_iw_ss_cache_t **spec_scan_head; + mutex_lock(&wl_cache_lock); spec_scan_head = &g_ss_cache_ctrl.m_cache_head; node = *spec_scan_head; prev = node; @@ -2518,8 +2525,8 @@ wl_iw_delete_bss_from_ss_cache(void *addr) } memset(addr, 0, ETHER_ADDR_LEN); + mutex_unlock(&wl_cache_lock); return 0; - } @@ -2915,7 +2922,6 @@ wl_iw_get_scan( iscan_buf_t * p_buf; uint32 counter = 0; #endif - WL_TRACE(("%s: buflen_from_user %d: \n", dev->name, buflen_from_user)); if (!extra) { @@ -2988,6 +2994,7 @@ wl_iw_get_scan( kfree(list); } + mutex_lock(&wl_cache_lock); #if defined(WL_IW_USE_ISCAN) if (g_scan_specified_ssid) WL_TRACE(("%s: Specified scan APs from scan=%d\n", __FUNCTION__, list->count)); @@ -3007,11 +3014,11 @@ wl_iw_get_scan( list_merge = (wl_scan_results_t *) g_scan; len_ret = (__u16) wl_iw_get_scan_prep(list_merge, info, extra, buflen_from_user); #endif + mutex_unlock(&wl_cache_lock); if (g_ss_cache_ctrl.m_link_down) { - wl_iw_delete_bss_from_ss_cache(g_ss_cache_ctrl.m_active_bssid); } - + wl_iw_merge_scan_cache(info, extra+len_ret, buflen_from_user-len_ret, &merged_len); len_ret += merged_len; wl_iw_run_ss_cache_timer(0); @@ -3078,8 +3085,6 @@ wl_iw_iscan_get_scan( return wl_iw_get_scan(dev, info, dwrq, extra); } - - if (g_ss_cache_ctrl.m_timer_expired) { wl_iw_free_ss_cache(); g_ss_cache_ctrl.m_timer_expired ^= 1; @@ -3089,12 +3094,11 @@ wl_iw_iscan_get_scan( } else { if (g_ss_cache_ctrl.m_link_down) { - wl_iw_delete_bss_from_ss_cache(g_ss_cache_ctrl.m_active_bssid); } if (g_ss_cache_ctrl.m_prev_scan_mode || g_ss_cache_ctrl.m_cons_br_scan_cnt > 4) { g_ss_cache_ctrl.m_cons_br_scan_cnt = 0; - + wl_iw_reset_ss_cache(); } g_ss_cache_ctrl.m_prev_scan_mode = g_scan_specified_ssid; @@ -3198,7 +3202,6 @@ wl_iw_iscan_get_scan( dwrq->length = event - extra; dwrq->flags = 0; - wl_iw_merge_scan_cache(info, event, buflen_from_user - dwrq->length, &merged_len); dwrq->length += merged_len; wl_iw_run_ss_cache_timer(0); @@ -3208,7 +3211,6 @@ wl_iw_iscan_get_scan( WL_TRACE(("%s return to WE %d bytes APs=%d\n", __FUNCTION__, dwrq->length, counter)); - if (!dwrq->length) return -EAGAIN; @@ -4728,11 +4730,24 @@ get_channel_retry: ASSERT(iolen); res |= dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen); + if (res != 0) { + WL_ERROR(("ERROR:%d in:%s, Security & BSS reconfiguration is skipped\n", + res, __FUNCTION__)); + return res; + } + if (!ap_cfg_running) { kernel_thread(thr_wait_for_2nd_eth_dev, 0, 0); } else { - WL_TRACE(("%s: Configure security & restart AP bss \n", __FUNCTION__)); - res |= wl_iw_set_ap_security(dev, &my_ap); + if (ap_net_dev == NULL) { + WL_ERROR(("%s: ERROR: ap_net_dev is NULL !!!\n",__FUNCTION__)); + return -1; + } + + /* if the AP interface wl0.1 already exists we call security & bss UP in here */ + WL_ERROR(("%s: %s Configure security & restart AP bss\n", __FUNCTION__, ap_net_dev->name)); + + res |= wl_iw_set_ap_security(ap_net_dev, &my_ap); res |= dev_iw_write_cfg1_bss_var(dev, 1); } return res; @@ -4964,21 +4979,70 @@ int get_parmeter_from_string( } +static int wl_iw_softap_deassoc_stations(struct net_device *dev) +{ + int i; + int res = 0; + char mac_buf[128] = {0}; + struct maclist *assoc_maclist = (struct maclist *)mac_buf; + + memset(assoc_maclist, 0, sizeof(mac_buf)); + assoc_maclist->count = 8; + + res = dev_wlc_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist, 128); + if (res != 0) { + WL_SOFTAP((" Error:%d in :%s, Couldn't get ASSOC List\n", res, __FUNCTION__)); + return res; + } + + if (assoc_maclist->count) { + for (i = 0; i < assoc_maclist->count; i++) { + scb_val_t scbval; + + scbval.val = htod32(1); + bcopy(&assoc_maclist->ea[i], &scbval.ea, ETHER_ADDR_LEN); + + WL_SOFTAP(("deauth STA:%d \n", i)); + res |= dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, + &scbval, sizeof(scb_val_t)); + } + } else { + WL_SOFTAP((" STA ASSOC list is empty\n")); + } + + if (res != 0) + WL_SOFTAP((" Error:%d in :%s\n", res, __FUNCTION__)); + return res; +} + + static int iwpriv_softap_stop(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *ext) { - int res; + int res = 0; + char buf[128]; - WL_SOFTAP((" iw_handler SOFTAP_STP \n")); + WL_SOFTAP(("got iwpriv AP_BSS_STOP\n")); - ap_mode = 0; - ap_cfg_running = FALSE; + if ((!dev) && (!ap_net_dev)) { + WL_ERROR(("%s: dev is null\n", __FUNCTION__)); + return res; + } - res = dev_iw_write_cfg1_bss_var(dev, 2); + /* Make sure that interface is UP */ + strcpy(buf, "cur_etheraddr"); + dev_wlc_ioctl(dev, WLC_GET_VAR, buf, sizeof(buf)); + + res = wl_iw_softap_deassoc_stations(ap_net_dev); + + bcm_mdelay(200); + res |= dev_iw_write_cfg1_bss_var(dev, 2); wrqu->data.length = 0; + ap_mode = 0; + ap_cfg_running = FALSE; return res; } @@ -6114,13 +6178,11 @@ wl_iw_bt_flag_set( #endif if (set == TRUE) { - - dev_wlc_bufvar_set(dev, "btc_flags", \ + dev_wlc_bufvar_set(dev, "btc_flags", (char *)&buf_flag7_dhcp_on[0], sizeof(buf_flag7_dhcp_on)); } else { - - dev_wlc_bufvar_set(dev, "btc_flags", \ + dev_wlc_bufvar_set(dev, "btc_flags", (char *)&buf_flag7_default[0], sizeof(buf_flag7_default)); } @@ -6135,7 +6197,7 @@ wl_iw_bt_timerfunc(ulong data) bt_info_t *bt_local = (bt_info_t *)data; bt_local->timer_on = 0; WL_TRACE(("%s\n", __FUNCTION__)); - + up(&bt_local->bt_sem); } @@ -6155,13 +6217,12 @@ _bt_dhcp_sysioc_thread(void *data) switch (g_bt->bt_state) { case BT_DHCP_START: - g_bt->bt_state = BT_DHCP_OPPORTUNITY_WINDOW; mod_timer(&g_bt->timer, jiffies + BT_DHCP_OPPORTUNITY_WINDOW_TIEM*HZ/1000); g_bt->timer_on = 1; break; + case BT_DHCP_OPPORTUNITY_WINDOW: - WL_TRACE(("%s waiting for %d msec expired, force bt flag\n", \ __FUNCTION__, BT_DHCP_OPPORTUNITY_WINDOW_TIEM)); if (g_bt->dev) wl_iw_bt_flag_set(g_bt->dev, TRUE); @@ -6169,8 +6230,8 @@ _bt_dhcp_sysioc_thread(void *data) mod_timer(&g_bt->timer, jiffies + BT_DHCP_FLAG_FORCE_TIME*HZ/1000); g_bt->timer_on = 1; break; + case BT_DHCP_FLAG_FORCE_TIMEOUT: - WL_TRACE(("%s waiting for %d msec expired remove bt flag\n", \ __FUNCTION__, BT_DHCP_FLAG_FORCE_TIME)); @@ -6178,6 +6239,7 @@ _bt_dhcp_sysioc_thread(void *data) g_bt->bt_state = BT_DHCP_IDLE; g_bt->timer_on = 0; break; + default: WL_ERROR(("%s error g_status=%d !!!\n", __FUNCTION__, \ g_bt->bt_state)); @@ -6252,7 +6314,12 @@ int wl_iw_attach(struct net_device *dev, void * dhdp) wl_iw_t *iw; #if defined(WL_IW_USE_ISCAN) iscan_info_t *iscan = NULL; +#endif + + mutex_init(&wl_cache_lock); + mutex_init(&wl_start_lock); +#if defined(WL_IW_USE_ISCAN) if (!dev) return 0; @@ -6268,7 +6335,6 @@ int wl_iw_attach(struct net_device *dev, void * dhdp) g_first_broadcast_scan = BROADCAST_SCAN_FIRST_IDLE; g_iscan->scan_flag = 0; - iscan->timer_ms = 3000; init_timer(&iscan->timer); iscan->timer.data = (ulong)iscan; @@ -6279,14 +6345,12 @@ int wl_iw_attach(struct net_device *dev, void * dhdp) iscan->sysioc_pid = kernel_thread(_iscan_sysioc_thread, iscan, 0); if (iscan->sysioc_pid < 0) return -ENOMEM; -#endif - mutex_init(&wl_start_lock); +#endif iw = *(wl_iw_t **)netdev_priv(dev); iw->pub = (dhd_pub_t *)dhdp; g_scan = NULL; - g_scan = (void *)kmalloc(G_SCAN_RESULTS, GFP_KERNEL); if (!g_scan) return -ENOMEM; @@ -6295,7 +6359,7 @@ int wl_iw_attach(struct net_device *dev, void * dhdp) g_scan_specified_ssid = 0; wl_iw_init_ss_cache_ctrl(); - + wl_iw_bt_init(dev); #ifdef SOFTAP @@ -6317,7 +6381,7 @@ void wl_iw_detach(void) KILL_PROC(iscan->sysioc_pid, SIGTERM); wait_for_completion(&iscan->sysioc_exited); } - + mutex_lock(&wl_cache_lock); while (iscan->list_hdr) { buf = iscan->list_hdr->next; kfree(iscan->list_hdr); @@ -6325,6 +6389,7 @@ void wl_iw_detach(void) } kfree(iscan); g_iscan = NULL; + mutex_unlock(&wl_cache_lock); #endif if (g_scan) @@ -6333,7 +6398,6 @@ void wl_iw_detach(void) g_scan = NULL; wl_iw_release_ss_cache_ctrl(); wl_iw_bt_release(); - #ifdef SOFTAP if (ap_mode) { WL_TRACE(("\n%s AP is going down\n", __FUNCTION__)); |