static int netdev_close(struct net_device *pnetdev) { struct _adapter *padapter = (struct _adapter *) _netdev_priv(pnetdev); /* Close LED*/ padapter->ledpriv.LedControlHandler(padapter, LED_CTL_POWER_OFF); msleep(200); /*s1.*/ if (pnetdev) { if (!netif_queue_stopped(pnetdev)) netif_stop_queue(pnetdev); } /*s2.*/ /*s2-1. issue disassoc_cmd to fw*/ r8712_disassoc_cmd(padapter); /*s2-2. indicate disconnect to os*/ r8712_ind_disconnect(padapter); /*s2-3.*/ r8712_free_assoc_resources(padapter); /*s2-4.*/ r8712_free_network_queue(padapter); /*Stop driver mlme relation timer*/ stop_drv_timers(padapter); return 0; }
/** * * This function intends to handle the shutdown of an interface * i.e. when it is brought Down from an Up/Active state. * */ static int netdev_close(struct net_device *pnetdev) { struct _adapter *padapter = (struct _adapter *) netdev_priv(pnetdev); /* Close LED*/ padapter->ledpriv.LedControlHandler(padapter, LED_CTL_POWER_OFF); msleep(200); /*s1.*/ if (pnetdev) { if (!netif_queue_stopped(pnetdev)) netif_stop_queue(pnetdev); } /*s2.*/ /*s2-1. issue disassoc_cmd to fw*/ r8712_disassoc_cmd(padapter); /*s2-2. indicate disconnect to os*/ r8712_ind_disconnect(padapter); /*s2-3.*/ r8712_free_assoc_resources(padapter); /*s2-4.*/ r8712_free_network_queue(padapter); /* The interface is no longer Up: */ padapter->bup = false; release_firmware(padapter->fw); /* never exit with a firmware callback pending */ wait_for_completion(&padapter->rtl8712_fw_ready); return 0; }
void r8712_stadel_event_callback(struct _adapter *adapter, u8 *pbuf) { unsigned long irqL, irqL2; struct sta_info *psta; struct wlan_network *pwlan = NULL; struct wlan_bssid_ex *pdev_network = NULL; u8 *pibss = NULL; struct mlme_priv *pmlmepriv = &adapter->mlmepriv; struct stadel_event *pstadel = (struct stadel_event *)pbuf; struct sta_priv *pstapriv = &adapter->stapriv; struct wlan_network *tgt_network = &pmlmepriv->cur_network; spin_lock_irqsave(&pmlmepriv->lock, irqL2); if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) { r8712_ind_disconnect(adapter); r8712_free_assoc_resources(adapter); } if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE)) { psta = r8712_get_stainfo(&adapter->stapriv, pstadel->macaddr); spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); r8712_free_stainfo(adapter, psta); spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); if (adapter->stapriv.asoc_sta_count == 1) { /*a sta + bc/mc_stainfo (not Ibss_stainfo) */ pwlan = r8712_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress); if (pwlan) { pwlan->fixed = false; free_network_nolock(pmlmepriv, pwlan); } /*re-create ibss*/ pdev_network = &(adapter->registrypriv.dev_network); pibss = adapter->registrypriv.dev_network.MacAddress; memcpy(pdev_network, &tgt_network->network, r8712_get_ndis_wlan_bssid_ex_sz(&tgt_network-> network)); memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid)); memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); r8712_update_registrypriv_dev_network(adapter); r8712_generate_random_ibss(pibss); if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE); } } } spin_unlock_irqrestore(&pmlmepriv->lock, irqL2); }
u8 r8712_set_802_11_disassociate(struct _adapter *padapter) { unsigned long irqL; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; spin_lock_irqsave(&pmlmepriv->lock, irqL); if (check_fwstate(pmlmepriv, _FW_LINKED) == true) { r8712_disassoc_cmd(padapter); r8712_ind_disconnect(padapter); r8712_free_assoc_resources(padapter); } spin_unlock_irqrestore(&pmlmepriv->lock, irqL); return true; }
u8 r8712_set_802_11_infrastructure_mode(struct _adapter *padapter, enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype) { unsigned long irqL; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *cur_network = &pmlmepriv->cur_network; enum NDIS_802_11_NETWORK_INFRASTRUCTURE *pold_state = &(cur_network->network.InfrastructureMode); if (*pold_state != networktype) { spin_lock_irqsave(&pmlmepriv->lock, irqL); if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) || (*pold_state == Ndis802_11IBSS)) r8712_disassoc_cmd(padapter); if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true) r8712_free_assoc_resources(padapter); if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) || (*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) { /* will clr Linked_state before this function, * we must have chked whether issue dis-assoc_cmd or * not */ r8712_ind_disconnect(padapter); } *pold_state = networktype; /* clear WIFI_STATION_STATE; WIFI_AP_STATE; WIFI_ADHOC_STATE; * WIFI_ADHOC_MASTER_STATE */ _clr_fwstate_(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE | WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE); switch (networktype) { case Ndis802_11IBSS: set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); break; case Ndis802_11Infrastructure: set_fwstate(pmlmepriv, WIFI_STATION_STATE); break; case Ndis802_11APMode: set_fwstate(pmlmepriv, WIFI_AP_STATE); break; case Ndis802_11AutoUnknown: case Ndis802_11InfrastructureMax: break; } spin_unlock_irqrestore(&pmlmepriv->lock, irqL); } return true; }
u8 r8712_set_802_11_bssid(struct _adapter *padapter, u8 *bssid) { unsigned long irqL; u8 status = true; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; if ((bssid[0] == 0x00 && bssid[1] == 0x00 && bssid[2] == 0x00 && bssid[3] == 0x00 && bssid[4] == 0x00 && bssid[5] == 0x00) || (bssid[0] == 0xFF && bssid[1] == 0xFF && bssid[2] == 0xFF && bssid[3] == 0xFF && bssid[4] == 0xFF && bssid[5] == 0xFF)) { status = false; return status; } spin_lock_irqsave(&pmlmepriv->lock, irqL); if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == true) { status = check_fwstate(pmlmepriv, _FW_UNDER_LINKING); goto _Abort_Set_BSSID; } if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true) { if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN)) { if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false) goto _Abort_Set_BSSID; /* driver is in * WIFI_ADHOC_MASTER_STATE */ } else { r8712_disassoc_cmd(padapter); if (check_fwstate(pmlmepriv, _FW_LINKED) == true) r8712_ind_disconnect(padapter); r8712_free_assoc_resources(padapter); if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } } memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN); pmlmepriv->assoc_by_bssid = true; status = do_join(padapter); goto done; _Abort_Set_BSSID: done: spin_unlock_irqrestore(&pmlmepriv->lock, irqL); return status; }
void r8712_set_802_11_ssid(struct _adapter *padapter, struct ndis_802_11_ssid *ssid) { unsigned long irqL; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *pnetwork = &pmlmepriv->cur_network; if (!padapter->hw_init_completed) return; spin_lock_irqsave(&pmlmepriv->lock, irqL); if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) { check_fwstate(pmlmepriv, _FW_UNDER_LINKING); goto _Abort_Set_SSID; } if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) { if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) && (!memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength))) { if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { if (!r8712_is_same_ibss(padapter, pnetwork)) { /* if in WIFI_ADHOC_MASTER_STATE or * WIFI_ADHOC_STATE, create bss or * rejoin again */ r8712_disassoc_cmd(padapter); if (check_fwstate(pmlmepriv, _FW_LINKED) == true) r8712_ind_disconnect(padapter); r8712_free_assoc_resources(padapter); if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } else goto _Abort_Set_SSID; /* driver is in * WIFI_ADHOC_MASTER_STATE */ } } else { r8712_disassoc_cmd(padapter); if (check_fwstate(pmlmepriv, _FW_LINKED) == true) r8712_ind_disconnect(padapter); r8712_free_assoc_resources(padapter); if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } } if (padapter->securitypriv.btkip_countermeasure == true) goto _Abort_Set_SSID; if (!validate_ssid(ssid)) goto _Abort_Set_SSID; memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid)); pmlmepriv->assoc_by_bssid = false; do_join(padapter); goto done; _Abort_Set_SSID: done: spin_unlock_irqrestore(&pmlmepriv->lock, irqL); }
int r8712_select_and_join_from_scan(struct mlme_priv *pmlmepriv) { struct list_head *phead; unsigned char *dst_ssid, *src_ssid; struct _adapter *adapter; struct __queue *queue = NULL; struct wlan_network *pnetwork = NULL; struct wlan_network *pnetwork_max_rssi = NULL; adapter = (struct _adapter *)pmlmepriv->nic_hdl; queue = &pmlmepriv->scanned_queue; phead = get_list_head(queue); pmlmepriv->pscanned = get_next(phead); while (1) { if (end_of_queue_search(phead, pmlmepriv->pscanned) == true) { if ((pmlmepriv->assoc_by_rssi == true) && (pnetwork_max_rssi != NULL)) { pnetwork = pnetwork_max_rssi; goto ask_for_joinbss; } return _FAIL; } pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list); if (pnetwork == NULL) return _FAIL; pmlmepriv->pscanned = get_next(pmlmepriv->pscanned); if (pmlmepriv->assoc_by_bssid == true) { dst_ssid = pnetwork->network.MacAddress; src_ssid = pmlmepriv->assoc_bssid; if (!memcmp(dst_ssid, src_ssid, ETH_ALEN)) { if (check_fwstate(pmlmepriv, _FW_LINKED)) { if (is_same_network(&pmlmepriv-> cur_network.network, &pnetwork->network)) { _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); /*r8712_indicate_connect again*/ r8712_indicate_connect(adapter); return 2; } r8712_disassoc_cmd(adapter); r8712_ind_disconnect(adapter); r8712_free_assoc_resources(adapter); } goto ask_for_joinbss; } } else if (pmlmepriv->assoc_ssid.SsidLength == 0) goto ask_for_joinbss; dst_ssid = pnetwork->network.Ssid.Ssid; src_ssid = pmlmepriv->assoc_ssid.Ssid; if ((pnetwork->network.Ssid.SsidLength == pmlmepriv->assoc_ssid.SsidLength) && (!memcmp(dst_ssid, src_ssid, pmlmepriv->assoc_ssid.SsidLength))) { if (pmlmepriv->assoc_by_rssi == true) { /* if the ssid is the same, select the bss * which has the max rssi*/ if (pnetwork_max_rssi) { if (pnetwork->network.Rssi > pnetwork_max_rssi->network.Rssi) pnetwork_max_rssi = pnetwork; } else pnetwork_max_rssi = pnetwork; } else if (is_desired_network(adapter, pnetwork)) { if (check_fwstate(pmlmepriv, _FW_LINKED)) { r8712_disassoc_cmd(adapter); r8712_free_assoc_resources(adapter); } goto ask_for_joinbss; } } } return _FAIL; ask_for_joinbss: return r8712_joinbss_cmd(adapter, pnetwork); }