/******************************************************************************
*
* Copyright(c) 2007 - 2019 Realtek Corporation.
*
* 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.
*
*****************************************************************************/
#define _RTW_MLME_EXT_C_
#include <drv_types.h>
#include <hal_data.h>
struct mlme_handler mlme_sta_tbl[] = {
{WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq},
{WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp},
{WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq},
{WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp},
{WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq},
{WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp},
/*----------------------------------------------------------
below 2 are reserved
-----------------------------------------------------------*/
{0, "DoReserved", &DoReserved},
{0, "DoReserved", &DoReserved},
{WIFI_BEACON, "OnBeacon", &OnBeacon},
{WIFI_ATIM, "OnATIM", &OnAtim},
{WIFI_DISASSOC, "OnDisassoc", &OnDisassoc},
{WIFI_AUTH, "OnAuth", &OnAuthClient},
{WIFI_DEAUTH, "OnDeAuth", &OnDeAuth},
{WIFI_ACTION, "OnAction", &OnAction},
{WIFI_ACTION_NOACK, "OnActionNoAck", &OnAction},
};
#ifdef _CONFIG_NATIVEAP_MLME_
struct mlme_handler mlme_ap_tbl[] = {
{WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq},
{WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp},
{WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq},
{WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp},
{WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq},
{WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp},
/*----------------------------------------------------------
below 2 are reserved
-----------------------------------------------------------*/
{0, "DoReserved", &DoReserved},
{0, "DoReserved", &DoReserved},
{WIFI_BEACON, "OnBeacon", &OnBeacon},
{WIFI_ATIM, "OnATIM", &OnAtim},
{WIFI_DISASSOC, "OnDisassoc", &OnDisassoc},
{WIFI_AUTH, "OnAuth", &OnAuth},
{WIFI_DEAUTH, "OnDeAuth", &OnDeAuth},
{WIFI_ACTION, "OnAction", &OnAction},
{WIFI_ACTION_NOACK, "OnActionNoAck", &OnAction},
};
#endif
struct action_handler OnAction_tbl[] = {
{RTW_WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct},
{RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction_qos},
{RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction_dls},
{RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back},
{RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public},
{RTW_WLAN_CATEGORY_RADIO_MEAS, "ACTION_RADIO_MEAS", &on_action_rm},
{RTW_WLAN_CATEGORY_FT, "ACTION_FT", &OnAction_ft},
{RTW_WLAN_CATEGORY_HT, "ACTION_HT", &OnAction_ht},
#ifdef CONFIG_IEEE80211W
{RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &OnAction_sa_query},
#else
{RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved},
#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_RTW_WNM
{RTW_WLAN_CATEGORY_WNM, "ACTION_WNM", &on_action_wnm},
#endif
{RTW_WLAN_CATEGORY_UNPROTECTED_WNM, "ACTION_UNPROTECTED_WNM", &DoReserved},
#ifdef CONFIG_RTW_MESH
{RTW_WLAN_CATEGORY_MESH, "ACTION_MESH", &on_action_mesh},
{RTW_WLAN_CATEGORY_SELF_PROTECTED, "ACTION_SELF_PROTECTED", &on_action_self_protected},
#endif
{RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm},
{RTW_WLAN_CATEGORY_VHT, "ACTION_VHT", &OnAction_vht},
{RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p},
#ifdef CONFIG_RTW_TOKEN_BASED_XMIT
{RTW_WLAN_CATEGORY_TBTX, "ACTION_TBTX_TOKEN", &OnAction_tbtx_token}
#endif
};
u8 null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
/**************************************************
OUI definitions for the vendor specific IE
***************************************************/
unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02};
unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
unsigned char P2P_OUI[] = {0x50, 0x6F, 0x9A, 0x09};
unsigned char WFD_OUI[] = {0x50, 0x6F, 0x9A, 0x0A};
unsigned char DPP_OUI[] = {0x50, 0x6F, 0x9A, 0x1A};
unsigned char MULTI_AP_OUI[] = {0x50, 0x6F, 0x9A, 0x1B};
unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02};
unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02};
#ifdef CONFIG_RTW_TOKEN_BASED_XMIT
unsigned char REALTEK_TBTX_IE[] = {0x00, 0xe0, 0x4c, 0x01, 0x00, 0x00, 0x00, 0x00};
#endif
extern unsigned char REALTEK_96B_IE[];
static void init_channel_list(_adapter *padapter, RT_CHANNEL_INFO *channel_set
, struct p2p_channels *channel_list)
{
struct registry_priv *regsty = adapter_to_regsty(padapter);
struct p2p_oper_class_map op_class[] = {
{ IEEE80211G, 81, 1, 13, 1, BW20 },
{ IEEE80211G, 82, 14, 14, 1, BW20 },
#if 0 /* Do not enable HT40 on 2 GHz */
{ IEEE80211G, 83, 1, 9, 1, BW40PLUS },
{ IEEE80211G, 84, 5, 13, 1, BW40MINUS },
#endif
{ IEEE80211A, 115, 36, 48, 4, BW20 },
{ IEEE80211A, 116, 36, 44, 8, BW40PLUS },
{ IEEE80211A, 117, 40, 48, 8, BW40MINUS },
{ IEEE80211A, 124, 149, 161, 4, BW20 },
{ IEEE80211A, 125, 149, 169, 4, BW20 },
{ IEEE80211A, 126, 149, 157, 8, BW40PLUS },
{ IEEE80211A, 127, 153, 161, 8, BW40MINUS },
{ -1, 0, 0, 0, 0, BW20 }
};
int cla, op;
cla = 0;
for (op = 0; op_class[op].op_class; op++) {
u8 ch;
struct p2p_oper_class_map *o = &op_class[op];
struct p2p_reg_class *reg = NULL;
for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
if (rtw_chset_search_ch(channel_set, ch) == -1)
continue;
#if defined(CONFIG_80211N_HT) || defined(CONFIG_80211AC_VHT)
if ((padapter->registrypriv.ht_enable == 0) && (o->inc == 8))
continue;
if ((REGSTY_IS_BW_5G_SUPPORT(regsty, CHANNEL_WIDTH_40)) &&
((o->bw == BW40MINUS) || (o->bw == BW40PLUS)))
continue;
#endif
if (reg == NULL) {
reg = &channel_list->reg_class[cla];
cla++;
reg->reg_class = o->op_class;
reg->channels = 0;
}
reg->channel[reg->channels] = ch;
reg->channels++;
}
}
channel_list->reg_classes = cla;
}
#if CONFIG_TXPWR_LIMIT
void rtw_txpwr_init_regd(struct rf_ctl_t *rfctl)
{
u8 regd;
struct regd_exc_ent *exc;
struct txpwr_lmt_ent *ent;
_irqL irqL;
_enter_critical_mutex(&rfctl->txpwr_lmt_mutex, &irqL);
rfctl->regd_name = NULL;
if (rfctl->txpwr_regd_num == 0) {
RTW_PRINT("there is no any txpwr_regd\n");
goto release_lock;
}
/* search from exception mapping */
exc = _rtw_regd_exc_search(rfctl
, rfctl->country_ent ? rfctl->country_ent->alpha2 : NULL
, rfctl->ChannelPlan);
if (exc) {
u8 has_country = (exc->country[0] == '\0' && exc->country[1] == '\0') ? 0 : 1;
if (strcmp(exc->regd_name, regd_str(TXPWR_LMT_NONE)) == 0)
rfctl->regd_name = regd_str(TXPWR_LMT_NONE);
else if (strcmp(exc->regd_name, regd_str(TXPWR_LMT_WW)) == 0)
rfctl->regd_name = regd_str(TXPWR_LMT_WW);
else {
ent = _rtw_txpwr_lmt_get_by_name(rfctl, exc->regd_name);
if (ent)
rfctl->regd_name = ent->regd_name;
}
RTW_PRINT("exception mapping country:%c%c domain:0x%02x to%s regd_name:%s\n"
, has_country ? exc->country[0] : '0'
, has_country ? exc->country[1] : '0'
, exc->domain
, rfctl->regd_name ? "" : " unknown"
, exc->regd_name
);
if (rfctl->regd_name)
goto release_lock;
}
/* follow default channel plan mapping */
regd = rtw_chplan_get_default_regd(rfctl->ChannelPlan);
if (regd == TXPWR_LMT_NONE)
rfctl->regd_name = regd_str(TXPWR_LMT_NONE);
else if (regd == TXPWR_LMT_WW)
rfctl->regd_name = regd_str(TXPWR_LMT_WW);
else {
ent = _rtw_txpwr_lmt_get_by_name(rfctl, regd_str(regd));
if (ent)
rfctl->regd_name = ent->regd_name;