mirror of
https://github.com/chinawrj/rtl8812au
synced 2025-02-05 15:32:00 +08:00
41ea46fa15
This reverts commit c7f8f6e3633bd91a9f359eb3406beb972e58cd7b. This commit is reverted because it introduces such issues as monitor stops working. Before the issue is solved, we should keep the code on main branch work
596 lines
18 KiB
C
596 lines
18 KiB
C
/******************************************************************************
|
|
*
|
|
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of version 2 of the GNU General Public License as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
|
*
|
|
*
|
|
******************************************************************************/
|
|
#define _RTW_RSON_C_
|
|
|
|
#include <drv_types.h>
|
|
|
|
#ifdef CONFIG_RTW_REPEATER_SON
|
|
|
|
/******** Custommize Part ***********************/
|
|
|
|
unsigned char RTW_RSON_OUI[] = {0xFA, 0xFA, 0xFA};
|
|
#define RSON_SCORE_DIFF_TH 8
|
|
|
|
/*
|
|
Calculate the corresponding score.
|
|
*/
|
|
inline u8 rtw_cal_rson_score(struct rtw_rson_struct *cand_rson_data, NDIS_802_11_RSSI Rssi)
|
|
{
|
|
if ((cand_rson_data->hopcnt == RTW_RSON_HC_NOTREADY)
|
|
|| (cand_rson_data->connectible == RTW_RSON_DENYCONNECT))
|
|
return RTW_RSON_SCORE_NOTCNNT;
|
|
|
|
return RTW_RSON_SCORE_MAX - (cand_rson_data->hopcnt * 10) + (Rssi/10);
|
|
}
|
|
|
|
/*************************************************/
|
|
|
|
|
|
static u8 rtw_rson_block_bssid_idx = 0;
|
|
u8 rtw_rson_block_bssid[10][6] = {
|
|
/*{0x02, 0xE0, 0x4C, 0x07, 0xC3, 0xF6}*/
|
|
};
|
|
|
|
/* fake root, regard a real AP as a SO root */
|
|
static u8 rtw_rson_root_bssid_idx = 0;
|
|
u8 rtw_rson_root_bssid[10][6] = {
|
|
/*{0x1c, 0x5f, 0x2b, 0x5a, 0x60, 0x24}*/
|
|
};
|
|
|
|
int is_match_bssid(u8 *mac, u8 bssid_array[][6], int num)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < num; i++)
|
|
if (_rtw_memcmp(mac, bssid_array[i], 6) == _TRUE)
|
|
return _TRUE;
|
|
return _FALSE;
|
|
}
|
|
|
|
void init_rtw_rson_data(struct dvobj_priv *dvobj)
|
|
{
|
|
/*Aries todo. if pdvobj->rson_data.ver == 1 */
|
|
dvobj->rson_data.ver = RTW_RSON_VER;
|
|
dvobj->rson_data.id = CONFIG_RTW_REPEATER_SON_ID;
|
|
#ifdef CONFIG_RTW_REPEATER_SON_ROOT
|
|
dvobj->rson_data.hopcnt = RTW_RSON_HC_ROOT;
|
|
dvobj->rson_data.connectible = RTW_RSON_ALLOWCONNECT;
|
|
#else
|
|
dvobj->rson_data.hopcnt = RTW_RSON_HC_NOTREADY;
|
|
dvobj->rson_data.connectible = RTW_RSON_DENYCONNECT;
|
|
#endif
|
|
dvobj->rson_data.loading = 0;
|
|
_rtw_memset(dvobj->rson_data.res, 0xAA, sizeof(dvobj->rson_data.res));
|
|
}
|
|
|
|
void rtw_rson_get_property_str(_adapter *padapter, char *rson_data_str)
|
|
{
|
|
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
|
|
|
|
sprintf(rson_data_str, "version : \t%d\nid : \t\t%08x\nhop count : \t%d\nconnectible : \t%s\nloading : \t%d\nreserve : \t%16ph\n",
|
|
pdvobj->rson_data.ver,
|
|
pdvobj->rson_data.id,
|
|
pdvobj->rson_data.hopcnt,
|
|
pdvobj->rson_data.connectible ? "connectable":"unconnectable",
|
|
pdvobj->rson_data.loading,
|
|
pdvobj->rson_data.res);
|
|
}
|
|
|
|
int str2hexbuf(char *str, u8 *hexbuf, int len)
|
|
{
|
|
u8 *p;
|
|
int i, slen, idx = 0;
|
|
|
|
p = (unsigned char *)str;
|
|
if ((*p != '0') || (*(p+1) != 'x'))
|
|
return _FALSE;
|
|
slen = strlen(str);
|
|
if (slen > (len*2) + 2)
|
|
return _FALSE;
|
|
p += 2;
|
|
for (i = 0 ; i < len; i++, idx = idx+2) {
|
|
hexbuf[i] = key_2char2num(p[idx], p[idx + 1]);
|
|
if (slen <= idx+2)
|
|
break;
|
|
}
|
|
return _TRUE;
|
|
}
|
|
|
|
int rtw_rson_set_property(_adapter *padapter, char *field, char *value)
|
|
{
|
|
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
|
|
int num = 0;
|
|
|
|
if (_rtw_memcmp(field, (u8 *)"ver", 3) == _TRUE)
|
|
pdvobj->rson_data.ver = rtw_atoi(value);
|
|
else if (_rtw_memcmp(field, (u8 *)"id", 2) == _TRUE)
|
|
num = sscanf(value, "%08x", &(pdvobj->rson_data.id));
|
|
else if (_rtw_memcmp(field, (u8 *)"hc", 2) == _TRUE)
|
|
num = sscanf(value, "%hhu", &(pdvobj->rson_data.hopcnt));
|
|
else if (_rtw_memcmp(field, (u8 *)"cnt", 3) == _TRUE)
|
|
num = sscanf(value, "%hhu", &(pdvobj->rson_data.connectible));
|
|
else if (_rtw_memcmp(field, (u8 *)"loading", 2) == _TRUE)
|
|
num = sscanf(value, "%hhu", &(pdvobj->rson_data.loading));
|
|
else if (_rtw_memcmp(field, (u8 *)"res", 2) == _TRUE) {
|
|
str2hexbuf(value, pdvobj->rson_data.res, 16);
|
|
return 1;
|
|
} else
|
|
return _FALSE;
|
|
return num;
|
|
}
|
|
|
|
/*
|
|
return : TRUE -- competitor is taking advantage than condidate
|
|
FALSE -- we should continue keeping candidate
|
|
*/
|
|
int rtw_rson_choose(struct wlan_network **candidate, struct wlan_network *competitor)
|
|
{
|
|
s16 comp_score = 0, cand_score = 0;
|
|
struct rtw_rson_struct rson_cand, rson_comp;
|
|
|
|
if (is_match_bssid(competitor->network.MacAddress, rtw_rson_block_bssid, rtw_rson_block_bssid_idx) == _TRUE)
|
|
return _FALSE;
|
|
|
|
if ((competitor == NULL)
|
|
|| (rtw_get_rson_struct(&(competitor->network), &rson_comp) != _TRUE)
|
|
|| (rson_comp.id != CONFIG_RTW_REPEATER_SON_ID))
|
|
return _FALSE;
|
|
|
|
comp_score = rtw_cal_rson_score(&rson_comp, competitor->network.Rssi);
|
|
if (comp_score == RTW_RSON_SCORE_NOTCNNT)
|
|
return _FALSE;
|
|
|
|
if (*candidate == NULL)
|
|
return _TRUE;
|
|
if (rtw_get_rson_struct(&((*candidate)->network), &rson_cand) != _TRUE)
|
|
return _FALSE;
|
|
|
|
cand_score = rtw_cal_rson_score(&rson_cand, (*candidate)->network.Rssi);
|
|
RTW_INFO("%s: competitor_score=%d, candidate_score=%d\n", __func__, comp_score, cand_score);
|
|
if (comp_score - cand_score > RSON_SCORE_DIFF_TH)
|
|
return _TRUE;
|
|
|
|
return _FALSE;
|
|
}
|
|
|
|
inline u8 rtw_rson_varify_ie(u8 *p)
|
|
{
|
|
u8 *ptr = NULL;
|
|
u8 ver;
|
|
u32 id;
|
|
u8 hopcnt;
|
|
u8 allcnnt;
|
|
|
|
ptr = p + 2 + sizeof(RTW_RSON_OUI);
|
|
ver = *ptr;
|
|
|
|
/* for (ver == 1) */
|
|
if (ver != 1)
|
|
return _FALSE;
|
|
|
|
return _TRUE;
|
|
}
|
|
|
|
/*
|
|
Parsing RTK self-organization vendor IE
|
|
*/
|
|
int rtw_get_rson_struct(WLAN_BSSID_EX *bssid, struct rtw_rson_struct *rson_data)
|
|
{
|
|
sint limit = 0;
|
|
u32 len;
|
|
u8 *p;
|
|
|
|
if ((rson_data == NULL) || (bssid == NULL))
|
|
return -EINVAL;
|
|
|
|
/* Default */
|
|
rson_data->id = 0;
|
|
rson_data->ver = 0;
|
|
rson_data->hopcnt = 0;
|
|
rson_data->connectible = 0;
|
|
rson_data->loading = 0;
|
|
/* fake root */
|
|
if (is_match_bssid(bssid->MacAddress, rtw_rson_root_bssid, rtw_rson_root_bssid_idx) == _TRUE) {
|
|
rson_data->id = CONFIG_RTW_REPEATER_SON_ID;
|
|
rson_data->ver = RTW_RSON_VER;
|
|
rson_data->hopcnt = RTW_RSON_HC_ROOT;
|
|
rson_data->connectible = RTW_RSON_ALLOWCONNECT;
|
|
rson_data->loading = 0;
|
|
return _TRUE;
|
|
}
|
|
limit = bssid->IELength - _BEACON_IE_OFFSET_;
|
|
|
|
for (p = bssid->IEs + _BEACON_IE_OFFSET_; ; p += (len + 2)) {
|
|
p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &len, limit);
|
|
limit -= len;
|
|
if ((p == NULL) || (len == 0))
|
|
break;
|
|
if (p && (_rtw_memcmp(p + 2, RTW_RSON_OUI, sizeof(RTW_RSON_OUI)) == _TRUE)
|
|
&& rtw_rson_varify_ie(p)) {
|
|
p = p + 2 + sizeof(RTW_RSON_OUI);
|
|
rson_data->ver = *p;
|
|
/* for (ver == 1) */
|
|
p = p + 1;
|
|
rson_data->id = le32_to_cpup((__le32 *)p);
|
|
p = p + 4;
|
|
rson_data->hopcnt = *p;
|
|
p = p + 1;
|
|
rson_data->connectible = *p;
|
|
p = p + 1;
|
|
rson_data->loading = *p;
|
|
|
|
return _TRUE;
|
|
}
|
|
}
|
|
return -EBADMSG;
|
|
}
|
|
|
|
u32 rtw_rson_append_ie(_adapter *padapter, unsigned char *pframe, u32 *len)
|
|
{
|
|
u8 *ptr, *ori, ie_len = 0;
|
|
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
|
|
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
|
|
/* static int iii = 0;*/
|
|
|
|
if ((!pdvobj) || (!pframe))
|
|
return 0;
|
|
ptr = ori = pframe;
|
|
*ptr++ = _VENDOR_SPECIFIC_IE_;
|
|
*ptr++ = ie_len = sizeof(RTW_RSON_OUI)+sizeof(pdvobj->rson_data);
|
|
_rtw_memcpy(ptr, RTW_RSON_OUI, sizeof(RTW_RSON_OUI));
|
|
ptr = ptr + sizeof(RTW_RSON_OUI);
|
|
*ptr++ = pdvobj->rson_data.ver;
|
|
*(s32 *)ptr = cpu_to_le32(pdvobj->rson_data.id);
|
|
ptr = ptr + sizeof(pdvobj->rson_data.id);
|
|
*ptr++ = pdvobj->rson_data.hopcnt;
|
|
*ptr++ = pdvobj->rson_data.connectible;
|
|
*ptr++ = pdvobj->rson_data.loading;
|
|
_rtw_memcpy(ptr, pdvobj->rson_data.res, sizeof(pdvobj->rson_data.res));
|
|
pframe = ptr;
|
|
/*
|
|
iii = iii % 20;
|
|
if (iii++ == 0)
|
|
RTW_INFO("%s : RTW RSON IE : %20ph\n", __func__, ori);
|
|
*/
|
|
*len += (ie_len+2);
|
|
return ie_len;
|
|
|
|
}
|
|
|
|
void rtw_rson_do_disconnect(_adapter *padapter)
|
|
{
|
|
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
|
|
|
|
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
|
|
#ifndef CONFIG_RTW_REPEATER_SON_ROOT
|
|
pdvobj->rson_data.ver = RTW_RSON_VER;
|
|
pdvobj->rson_data.id = CONFIG_RTW_REPEATER_SON_ID;
|
|
pdvobj->rson_data.hopcnt = RTW_RSON_HC_NOTREADY;
|
|
pdvobj->rson_data.connectible = RTW_RSON_DENYCONNECT;
|
|
pdvobj->rson_data.loading = 0;
|
|
rtw_mi_tx_beacon_hdl(padapter);
|
|
#endif
|
|
}
|
|
|
|
void rtw_rson_join_done(_adapter *padapter)
|
|
{
|
|
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
|
|
WLAN_BSSID_EX *cur_network = NULL;
|
|
struct rtw_rson_struct rson_data;
|
|
|
|
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
|
|
if (!padapter->mlmepriv.cur_network_scanned)
|
|
return;
|
|
cur_network = &(padapter->mlmepriv.cur_network_scanned->network);
|
|
if (rtw_get_rson_struct(cur_network, &rson_data) != _TRUE) {
|
|
RTW_ERR("%s: try to join a improper network(%s)\n", __func__, cur_network->Ssid.Ssid);
|
|
return;
|
|
}
|
|
|
|
#ifndef CONFIG_RTW_REPEATER_SON_ROOT
|
|
/* update rson_data */
|
|
pdvobj->rson_data.ver = RTW_RSON_VER;
|
|
pdvobj->rson_data.id = rson_data.id;
|
|
pdvobj->rson_data.hopcnt = rson_data.hopcnt + 1;
|
|
pdvobj->rson_data.connectible = RTW_RSON_ALLOWCONNECT;
|
|
pdvobj->rson_data.loading = 0;
|
|
rtw_mi_tx_beacon_hdl(padapter);
|
|
#endif
|
|
}
|
|
|
|
int rtw_rson_isupdate_roamcan(struct mlme_priv *mlme
|
|
, struct wlan_network **candidate, struct wlan_network *competitor)
|
|
{
|
|
struct rtw_rson_struct rson_cand, rson_comp, rson_curr;
|
|
s16 comp_score, cand_score, curr_score;
|
|
|
|
if ((competitor == NULL)
|
|
|| (rtw_get_rson_struct(&(competitor->network), &rson_comp) != _TRUE)
|
|
|| (rson_comp.id != CONFIG_RTW_REPEATER_SON_ID))
|
|
return _FALSE;
|
|
|
|
if (is_match_bssid(competitor->network.MacAddress, rtw_rson_block_bssid, rtw_rson_block_bssid_idx) == _TRUE)
|
|
return _FALSE;
|
|
|
|
if ((!mlme->cur_network_scanned)
|
|
|| (mlme->cur_network_scanned == competitor)
|
|
|| (rtw_get_rson_struct(&(mlme->cur_network_scanned->network), &rson_curr)) != _TRUE)
|
|
return _FALSE;
|
|
|
|
if (rtw_get_passing_time_ms((u32)competitor->last_scanned) >= mlme->roam_scanr_exp_ms)
|
|
return _FALSE;
|
|
|
|
comp_score = rtw_cal_rson_score(&rson_comp, competitor->network.Rssi);
|
|
curr_score = rtw_cal_rson_score(&rson_curr, mlme->cur_network_scanned->network.Rssi);
|
|
if (comp_score - curr_score < RSON_SCORE_DIFF_TH)
|
|
return _FALSE;
|
|
|
|
if (*candidate == NULL)
|
|
return _TRUE;
|
|
|
|
if (rtw_get_rson_struct(&((*candidate)->network), &rson_cand) != _TRUE) {
|
|
RTW_ERR("%s : Unable to get rson_struct from candidate(%s -- " MAC_FMT")\n",
|
|
__func__, (*candidate)->network.Ssid.Ssid, MAC_ARG((*candidate)->network.MacAddress));
|
|
return _FALSE;
|
|
}
|
|
cand_score = rtw_cal_rson_score(&rson_cand, (*candidate)->network.Rssi);
|
|
RTW_DBG("comp_score=%d , cand_score=%d , curr_score=%d\n", comp_score, cand_score, curr_score);
|
|
if (cand_score < comp_score)
|
|
return _TRUE;
|
|
|
|
#if 0 /* Handle 11R protocol */
|
|
#ifdef CONFIG_RTW_80211R
|
|
if (rtw_chk_ft_flags(adapter, RTW_FT_SUPPORTED)) {
|
|
ptmp = rtw_get_ie(&competitor->network.IEs[12], _MDIE_, &mdie_len, competitor->network.IELength-12);
|
|
if (ptmp) {
|
|
if (!_rtw_memcmp(&pftpriv->mdid, ptmp+2, 2))
|
|
goto exit;
|
|
|
|
/*The candidate don't support over-the-DS*/
|
|
if (rtw_chk_ft_flags(adapter, RTW_FT_STA_OVER_DS_SUPPORTED)) {
|
|
if ((rtw_chk_ft_flags(adapter, RTW_FT_OVER_DS_SUPPORTED) && !(*(ptmp+4) & 0x01)) ||
|
|
(!rtw_chk_ft_flags(adapter, RTW_FT_OVER_DS_SUPPORTED) && (*(ptmp+4) & 0x01))) {
|
|
RTW_INFO("FT: ignore the candidate(" MAC_FMT ") for over-the-DS\n", MAC_ARG(competitor->network.MacAddress));
|
|
rtw_clr_ft_flags(adapter, RTW_FT_OVER_DS_SUPPORTED);
|
|
goto exit;
|
|
}
|
|
}
|
|
} else
|
|
goto exit;
|
|
}
|
|
#endif
|
|
#endif
|
|
return _FALSE;
|
|
}
|
|
|
|
void rtw_rson_show_survey_info(struct seq_file *m, _list *plist, _list *phead)
|
|
{
|
|
struct wlan_network *pnetwork = NULL;
|
|
struct rtw_rson_struct rson_data;
|
|
s16 rson_score;
|
|
u16 index = 0;
|
|
|
|
RTW_PRINT_SEL(m, "%5s %-17s %3s %5s %14s %10s %-3s %5s %32s\n", "index", "bssid", "ch", "id", "hop_cnt", "loading", "RSSI", "score", "ssid");
|
|
while (1) {
|
|
if (rtw_end_of_queue_search(phead, plist) == _TRUE)
|
|
break;
|
|
|
|
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
|
|
if (!pnetwork)
|
|
break;
|
|
|
|
_rtw_memset(&rson_data, 0, sizeof(rson_data));
|
|
rson_score = 0;
|
|
if (rtw_get_rson_struct(&(pnetwork->network), &rson_data) == _TRUE)
|
|
rson_score = rtw_cal_rson_score(&rson_data, pnetwork->network.Rssi);
|
|
RTW_PRINT_SEL(m, "%5d "MAC_FMT" %3d 0x%08x %6d %10d %6d %6d %32s\n",
|
|
++index,
|
|
MAC_ARG(pnetwork->network.MacAddress),
|
|
pnetwork->network.Configuration.DSConfig,
|
|
rson_data.id,
|
|
rson_data.hopcnt,
|
|
rson_data.loading,
|
|
(int)pnetwork->network.Rssi,
|
|
rson_score,
|
|
pnetwork->network.Ssid.Ssid);
|
|
plist = get_next(plist);
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
Description : As a AP role, We need to check the qualify of associating STA.
|
|
We also need to check if we are ready to be associated.
|
|
|
|
return : TRUE -- AP REJECT this STA
|
|
FALSE -- AP ACCEPT this STA
|
|
*/
|
|
u8 rtw_rson_ap_check_sta(_adapter *padapter, u8 *pframe, uint pkt_len, unsigned short ie_offset)
|
|
{
|
|
struct wlan_network *pnetwork = NULL;
|
|
struct rtw_rson_struct rson_target;
|
|
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
|
|
int len = 0;
|
|
u8 ret = _FALSE;
|
|
u8 *p;
|
|
|
|
#ifndef CONFIG_RTW_REPEATER_SON_ROOT
|
|
_rtw_memset(&rson_target, 0, sizeof(rson_target));
|
|
for (p = pframe + WLAN_HDR_A3_LEN + ie_offset; ; p += (len + 2)) {
|
|
p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
|
|
|
|
if ((p == NULL) || (len == 0))
|
|
break;
|
|
|
|
if (p && (_rtw_memcmp(p + 2, RTW_RSON_OUI, sizeof(RTW_RSON_OUI)) == _TRUE)
|
|
&& rtw_rson_varify_ie(p)) {
|
|
p = p + 2 + sizeof(RTW_RSON_OUI);
|
|
rson_target.ver = *p;
|
|
/* for (ver == 1) */
|
|
p = p + 1;
|
|
rson_target.id = le32_to_cpup((__le32 *)p);
|
|
p = p + 4;
|
|
rson_target.hopcnt = *p;
|
|
p = p + 1;
|
|
rson_target.connectible = *p;
|
|
p = p + 1;
|
|
rson_target.loading = *p;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (rson_target.id == 0) /* Normal STA, not a RSON STA */
|
|
ret = _FALSE;
|
|
else if (rson_target.id != pdvobj->rson_data.id) {
|
|
ret = _TRUE;
|
|
RTW_INFO("%s : Reject AssoReq because RSON ID not match, STA=%08x, our=%08x\n",
|
|
__func__, rson_target.id, pdvobj->rson_data.id);
|
|
} else if ((pdvobj->rson_data.hopcnt == RTW_RSON_HC_NOTREADY)
|
|
|| (pdvobj->rson_data.connectible == RTW_RSON_DENYCONNECT)) {
|
|
ret = _TRUE;
|
|
RTW_INFO("%s : Reject AssoReq becuase our hopcnt=%d or connectbile=%d\n",
|
|
__func__, pdvobj->rson_data.hopcnt, pdvobj->rson_data.connectible);
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
u8 rtw_rson_scan_wk_cmd(_adapter *padapter, int op)
|
|
{
|
|
struct cmd_obj *ph2c;
|
|
struct drvextra_cmd_parm *pdrvextra_cmd_parm;
|
|
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
|
|
u8 *extra_cmd_buf;
|
|
u8 res = _SUCCESS;
|
|
|
|
ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
|
|
if (ph2c == NULL) {
|
|
res = _FAIL;
|
|
goto exit;
|
|
}
|
|
|
|
pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
|
|
if (pdrvextra_cmd_parm == NULL) {
|
|
rtw_mfree((u8 *)ph2c, sizeof(struct cmd_obj));
|
|
res = _FAIL;
|
|
goto exit;
|
|
}
|
|
pdrvextra_cmd_parm->ec_id = RSON_SCAN_WK_CID;
|
|
pdrvextra_cmd_parm->type = op;
|
|
pdrvextra_cmd_parm->size = 0;
|
|
pdrvextra_cmd_parm->pbuf = NULL;
|
|
|
|
init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
|
|
|
|
res = rtw_enqueue_cmd(pcmdpriv, ph2c);
|
|
|
|
exit:
|
|
return res;
|
|
|
|
}
|
|
|
|
void rtw_rson_scan_cmd_hdl(_adapter *padapter, int op)
|
|
{
|
|
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
|
|
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
|
|
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
|
u8 val8;
|
|
|
|
if (mlmeext_chk_scan_state(pmlmeext, SCAN_DISABLE) != _TRUE)
|
|
return;
|
|
if (op == RSON_SCAN_PROCESS) {
|
|
padapter->rtw_rson_scanstage = RSON_SCAN_PROCESS;
|
|
val8 = 0x1e;
|
|
rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &val8, _FALSE);
|
|
val8 = 1;
|
|
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
|
|
issue_probereq(padapter, NULL, NULL);
|
|
/* stop rson_scan after 100ms */
|
|
_set_timer(&(pmlmeext->rson_scan_timer), 100);
|
|
} else if (op == RSON_SCAN_DISABLE) {
|
|
padapter->rtw_rson_scanstage = RSON_SCAN_DISABLE;
|
|
val8 = 0;
|
|
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
|
|
val8 = 0xff;
|
|
rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &val8, _FALSE);
|
|
/* report_surveydone_event(padapter);*/
|
|
if (pmlmepriv->to_join == _TRUE) {
|
|
if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) != _TRUE) {
|
|
int s_ret;
|
|
|
|
set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
|
|
pmlmepriv->to_join = _FALSE;
|
|
s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
|
|
if (s_ret == _SUCCESS)
|
|
_set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
|
|
else if (s_ret == 2) {
|
|
_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
|
|
rtw_indicate_connect(padapter);
|
|
} else {
|
|
RTW_INFO("try_to_join, but select scanning queue fail, to_roam:%d\n", rtw_to_roam(padapter));
|
|
if (rtw_to_roam(padapter) != 0) {
|
|
if (rtw_dec_to_roam(padapter) == 0) {
|
|
rtw_set_to_roam(padapter, 0);
|
|
#ifdef CONFIG_INTEL_WIDI
|
|
if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_ROAMING) {
|
|
_rtw_memset(pmlmepriv->sa_ext, 0x00, L2SDTA_SERVICE_VE_LEN);
|
|
intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_WK, NULL, 0);
|
|
RTW_INFO("change to widi listen\n");
|
|
}
|
|
#endif /* CONFIG_INTEL_WIDI */
|
|
rtw_free_assoc_resources(padapter, _TRUE);
|
|
rtw_indicate_disconnect(padapter, 0, _FALSE);
|
|
} else
|
|
pmlmepriv->to_join = _TRUE;
|
|
} else
|
|
rtw_indicate_disconnect(padapter, 0, _FALSE);
|
|
_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
|
|
}
|
|
}
|
|
} else {
|
|
if (rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE)) {
|
|
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)
|
|
&& check_fwstate(pmlmepriv, _FW_LINKED)) {
|
|
if (rtw_select_roaming_candidate(pmlmepriv) == _SUCCESS) {
|
|
#ifdef CONFIG_RTW_80211R
|
|
if (rtw_chk_ft_flags(padapter, RTW_FT_OVER_DS_SUPPORTED)) {
|
|
start_clnt_ft_action(adapter, (u8 *)pmlmepriv->roam_network->network.MacAddress);
|
|
} else {
|
|
/*wait a little time to retrieve packets buffered in the current ap while scan*/
|
|
_set_timer(&pmlmeext->ft_roam_timer, 30);
|
|
}
|
|
#else
|
|
receive_disconnect(padapter, pmlmepriv->cur_network.network.MacAddress
|
|
, WLAN_REASON_ACTIVE_ROAM, _FALSE);
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
issue_action_BSSCoexistPacket(padapter);
|
|
issue_action_BSSCoexistPacket(padapter);
|
|
issue_action_BSSCoexistPacket(padapter);
|
|
}
|
|
} else {
|
|
RTW_ERR("%s : improper parameter -- op = %d\n", __func__, op);
|
|
}
|
|
}
|
|
|
|
#endif /* CONFIG_RTW_REPEATER_SON */
|