예제 #1
0
void r8712_stassoc_event_callback(struct _adapter *adapter, u8 *pbuf)
{
	unsigned long irqL;
	struct sta_info *psta;
	struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
	struct stassoc_event *pstassoc	= (struct stassoc_event *)pbuf;

	/* to do: */
	if (r8712_access_ctrl(&adapter->acl_list, pstassoc->macaddr) == false)
		return;
	psta = r8712_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
	if (psta != NULL) {
		/*the sta have been in sta_info_queue => do nothing
		 *(between drv has received this event before and
		 *  fw have not yet to set key to CAM_ENTRY) */
		return;
	}

	psta = r8712_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr);
	if (psta == NULL)
		return;
	/* to do : init sta_info variable */
	psta->qos_option = 0;
	psta->mac_id = le32_to_cpu((uint)pstassoc->cam_id);
	/* psta->aid = (uint)pstassoc->cam_id; */

	if (adapter->securitypriv.AuthAlgrthm == 2)
		psta->XPrivacy = adapter->securitypriv.PrivacyAlgrthm;
	psta->ieee8021x_blocked = false;
	spin_lock_irqsave(&pmlmepriv->lock, irqL);
	if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) ||
	    (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) {
		if (adapter->stapriv.asoc_sta_count == 2) {
			/* a sta + bc/mc_stainfo (not Ibss_stainfo) */
			r8712_indicate_connect(adapter);
		}
	}
	spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
}
예제 #2
0
void r8712_createbss_cmd_callback(struct _adapter *padapter,
				  struct cmd_obj *pcmd)
{
	unsigned long irqL;
	u8 timer_cancelled;
	struct sta_info *psta = NULL;
	struct wlan_network *pwlan = NULL;
	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
	struct ndis_wlan_bssid_ex *pnetwork = (struct ndis_wlan_bssid_ex *)
					      pcmd->parmbuf;
	struct wlan_network *tgt_network = &(pmlmepriv->cur_network);

	if (pcmd->res != H2C_SUCCESS)
		_set_timer(&pmlmepriv->assoc_timer, 1);
	_cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled);
#ifdef __BIG_ENDIAN
	/* endian_convert */
	pnetwork->Length = le32_to_cpu(pnetwork->Length);
	pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength);
	pnetwork->Privacy = le32_to_cpu(pnetwork->Privacy);
	pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi);
	pnetwork->NetworkTypeInUse = le32_to_cpu(pnetwork->NetworkTypeInUse);
	pnetwork->Configuration.ATIMWindow = le32_to_cpu(pnetwork->
					Configuration.ATIMWindow);
	pnetwork->Configuration.DSConfig = le32_to_cpu(pnetwork->
					Configuration.DSConfig);
	pnetwork->Configuration.FHConfig.DwellTime = le32_to_cpu(pnetwork->
					Configuration.FHConfig.DwellTime);
	pnetwork->Configuration.FHConfig.HopPattern = le32_to_cpu(pnetwork->
					Configuration.FHConfig.HopPattern);
	pnetwork->Configuration.FHConfig.HopSet = le32_to_cpu(pnetwork->
					Configuration.FHConfig.HopSet);
	pnetwork->Configuration.FHConfig.Length = le32_to_cpu(pnetwork->
					Configuration.FHConfig.Length);
	pnetwork->Configuration.Length = le32_to_cpu(pnetwork->
					Configuration.Length);
	pnetwork->InfrastructureMode = le32_to_cpu(pnetwork->
					   InfrastructureMode);
	pnetwork->IELength = le32_to_cpu(pnetwork->IELength);
#endif
	spin_lock_irqsave(&pmlmepriv->lock, irqL);
	if ((pmlmepriv->fw_state) & WIFI_AP_STATE) {
		psta = r8712_get_stainfo(&padapter->stapriv,
					 pnetwork->MacAddress);
		if (!psta) {
			psta = r8712_alloc_stainfo(&padapter->stapriv,
						   pnetwork->MacAddress);
			if (psta == NULL)
				goto createbss_cmd_fail;
		}
		r8712_indicate_connect(padapter);
	} else {
		pwlan = _r8712_alloc_network(pmlmepriv);
		if (pwlan == NULL) {
			pwlan = r8712_get_oldest_wlan_network(
				&pmlmepriv->scanned_queue);
			if (pwlan == NULL)
				goto createbss_cmd_fail;
			pwlan->last_scanned = jiffies;
		} else
			list_add_tail(&(pwlan->list),
					 &pmlmepriv->scanned_queue.queue);
		pnetwork->Length = r8712_get_ndis_wlan_bssid_ex_sz(pnetwork);
		memcpy(&(pwlan->network), pnetwork, pnetwork->Length);
		pwlan->fixed = true;
		memcpy(&tgt_network->network, pnetwork,
			(r8712_get_ndis_wlan_bssid_ex_sz(pnetwork)));
		if (pmlmepriv->fw_state & _FW_UNDER_LINKING)
			pmlmepriv->fw_state ^= _FW_UNDER_LINKING;
		/* we will set _FW_LINKED when there is one more sat to
		 * join us (stassoc_event_callback) */
	}
createbss_cmd_fail:
	spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
	r8712_free_cmd_obj(pcmd);
}
예제 #3
0
/*Notes:
 *pnetwork : returns from r8712_joinbss_event_callback
 *ptarget_wlan: found from scanned_queue
 *if join_res > 0, for (fw_state==WIFI_STATION_STATE), we check if
 *  "ptarget_sta" & "ptarget_wlan" exist.
 *if join_res > 0, for (fw_state==WIFI_ADHOC_STATE), we only check
 * if "ptarget_wlan" exist.
 *if join_res > 0, update "cur_network->network" from
 * "pnetwork->network" if (ptarget_wlan !=NULL).
 */
void r8712_joinbss_event_callback(struct _adapter *adapter, u8 *pbuf)
{
	unsigned long irqL = 0, irqL2;
	u8 timer_cancelled;
	struct sta_info	*ptarget_sta = NULL, *pcur_sta = NULL;
	struct sta_priv	*pstapriv = &adapter->stapriv;
	struct mlme_priv	*pmlmepriv = &adapter->mlmepriv;
	struct wlan_network	*cur_network = &pmlmepriv->cur_network;
	struct wlan_network	*pcur_wlan = NULL, *ptarget_wlan = NULL;
	unsigned int		the_same_macaddr = false;
	struct wlan_network *pnetwork;

	if (sizeof(struct list_head) == 4 * sizeof(u32)) {
		pnetwork = (struct wlan_network *)
			_malloc(sizeof(struct wlan_network));
		memcpy((u8 *)pnetwork+16, (u8 *)pbuf + 8,
			sizeof(struct wlan_network) - 16);
	} else
		pnetwork = (struct wlan_network *)pbuf;

#ifdef __BIG_ENDIAN
	/* endian_convert */
	pnetwork->join_res = le32_to_cpu(pnetwork->join_res);
	pnetwork->network_type = le32_to_cpu(pnetwork->network_type);
	pnetwork->network.Length = le32_to_cpu(pnetwork->network.Length);
	pnetwork->network.Ssid.SsidLength =
		 le32_to_cpu(pnetwork->network.Ssid.SsidLength);
	pnetwork->network.Privacy = le32_to_cpu(pnetwork->network.Privacy);
	pnetwork->network.Rssi = le32_to_cpu(pnetwork->network.Rssi);
	pnetwork->network.NetworkTypeInUse =
		 le32_to_cpu(pnetwork->network.NetworkTypeInUse);
	pnetwork->network.Configuration.ATIMWindow =
		 le32_to_cpu(pnetwork->network.Configuration.ATIMWindow);
	pnetwork->network.Configuration.BeaconPeriod =
		 le32_to_cpu(pnetwork->network.Configuration.BeaconPeriod);
	pnetwork->network.Configuration.DSConfig =
		 le32_to_cpu(pnetwork->network.Configuration.DSConfig);
	pnetwork->network.Configuration.FHConfig.DwellTime =
		 le32_to_cpu(pnetwork->network.Configuration.FHConfig.
			     DwellTime);
	pnetwork->network.Configuration.FHConfig.HopPattern =
		 le32_to_cpu(pnetwork->network.Configuration.
			     FHConfig.HopPattern);
	pnetwork->network.Configuration.FHConfig.HopSet =
		 le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopSet);
	pnetwork->network.Configuration.FHConfig.Length =
		 le32_to_cpu(pnetwork->network.Configuration.FHConfig.Length);
	pnetwork->network.Configuration.Length =
		 le32_to_cpu(pnetwork->network.Configuration.Length);
	pnetwork->network.InfrastructureMode =
		 le32_to_cpu(pnetwork->network.InfrastructureMode);
	pnetwork->network.IELength = le32_to_cpu(pnetwork->network.IELength);
#endif

	the_same_macaddr = !memcmp(pnetwork->network.MacAddress,
				   cur_network->network.MacAddress, ETH_ALEN);
	pnetwork->network.Length =
		 r8712_get_ndis_wlan_bssid_ex_sz(&pnetwork->network);
	spin_lock_irqsave(&pmlmepriv->lock, irqL);
	if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex))
		goto ignore_joinbss_callback;
	if (pnetwork->join_res > 0) {
		if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
			/*s1. find ptarget_wlan*/
			if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
				if (the_same_macaddr == true)
					ptarget_wlan =
					    r8712_find_network(&pmlmepriv->
					    scanned_queue,
					    cur_network->network.MacAddress);
				else {
					pcur_wlan =
					     r8712_find_network(&pmlmepriv->
					     scanned_queue,
					     cur_network->network.MacAddress);
					pcur_wlan->fixed = false;

					pcur_sta = r8712_get_stainfo(pstapriv,
					     cur_network->network.MacAddress);
					spin_lock_irqsave(&pstapriv->
						sta_hash_lock, irqL2);
					r8712_free_stainfo(adapter, pcur_sta);
					spin_unlock_irqrestore(&(pstapriv->
						sta_hash_lock), irqL2);

					ptarget_wlan =
						 r8712_find_network(&pmlmepriv->
						 scanned_queue,
						 pnetwork->network.
						 MacAddress);
					if (ptarget_wlan)
						ptarget_wlan->fixed = true;
				}
			} else {
				ptarget_wlan = r8712_find_network(&pmlmepriv->
						scanned_queue,
						pnetwork->network.MacAddress);
				if (ptarget_wlan)
					ptarget_wlan->fixed = true;
			}

			if (ptarget_wlan == NULL) {
				if (check_fwstate(pmlmepriv,
					_FW_UNDER_LINKING))
					pmlmepriv->fw_state ^=
						 _FW_UNDER_LINKING;
				goto ignore_joinbss_callback;
			}

			/*s2. find ptarget_sta & update ptarget_sta*/
			if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
				if (the_same_macaddr == true) {
					ptarget_sta =
						 r8712_get_stainfo(pstapriv,
						 pnetwork->network.MacAddress);
					if (ptarget_sta == NULL)
						ptarget_sta =
						 r8712_alloc_stainfo(pstapriv,
						 pnetwork->network.MacAddress);
				} else
					ptarget_sta =
						 r8712_alloc_stainfo(pstapriv,
						 pnetwork->network.MacAddress);
				if (ptarget_sta) /*update ptarget_sta*/ {
					ptarget_sta->aid = pnetwork->join_res;
					ptarget_sta->qos_option = 1;
					ptarget_sta->mac_id = 5;
					if (adapter->securitypriv.
					    AuthAlgrthm == 2) {
						adapter->securitypriv.
							binstallGrpkey =
							 false;
						adapter->securitypriv.
							busetkipkey =
							 false;
						adapter->securitypriv.
							bgrpkey_handshake =
							 false;
						ptarget_sta->ieee8021x_blocked
							 = true;
						ptarget_sta->XPrivacy =
							 adapter->securitypriv.
							 PrivacyAlgrthm;
						memset((u8 *)&ptarget_sta->
							 x_UncstKey,
							 0,
							 sizeof(union Keytype));
						memset((u8 *)&ptarget_sta->
							 tkiprxmickey,
							 0,
							 sizeof(union Keytype));
						memset((u8 *)&ptarget_sta->
							 tkiptxmickey,
							 0,
							 sizeof(union Keytype));
						memset((u8 *)&ptarget_sta->
							 txpn, 0,
							 sizeof(union pn48));
						memset((u8 *)&ptarget_sta->
							 rxpn, 0,
							 sizeof(union pn48));
					}
				} else {
					if (check_fwstate(pmlmepriv,
					    _FW_UNDER_LINKING))
						pmlmepriv->fw_state ^=
							 _FW_UNDER_LINKING;
					goto ignore_joinbss_callback;
				}
			}

			/*s3. update cur_network & indicate connect*/
			memcpy(&cur_network->network, &pnetwork->network,
				pnetwork->network.Length);
			cur_network->aid = pnetwork->join_res;
			/*update fw_state will clr _FW_UNDER_LINKING*/
			switch (pnetwork->network.InfrastructureMode) {
			case Ndis802_11Infrastructure:
				pmlmepriv->fw_state = WIFI_STATION_STATE;
				break;
			case Ndis802_11IBSS:
				pmlmepriv->fw_state = WIFI_ADHOC_STATE;
				break;
			default:
				pmlmepriv->fw_state = WIFI_NULL_STATE;
				break;
			}
			r8712_update_protection(adapter,
					  (cur_network->network.IEs) +
					  sizeof(struct NDIS_802_11_FIXED_IEs),
					  (cur_network->network.IELength));
			/*TODO: update HT_Capability*/
			update_ht_cap(adapter, cur_network->network.IEs,
				      cur_network->network.IELength);
			/*indicate connect*/
			if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)
				== true)
				r8712_indicate_connect(adapter);
			_cancel_timer(&pmlmepriv->assoc_timer,
				      &timer_cancelled);
		} else
			goto ignore_joinbss_callback;
	} else {
		if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
			_set_timer(&pmlmepriv->assoc_timer, 1);
			_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
		}
	}
ignore_joinbss_callback:
	spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
	if (sizeof(struct list_head) == 4 * sizeof(u32))
		kfree((u8 *)pnetwork);
}
예제 #4
0
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);
}