/* * This function maps the nl802.11 channel type into driver channel type. * * The mapping is as follows - * NL80211_CHAN_NO_HT -> IEEE80211_HT_PARAM_CHA_SEC_NONE * NL80211_CHAN_HT20 -> IEEE80211_HT_PARAM_CHA_SEC_NONE * NL80211_CHAN_HT40PLUS -> IEEE80211_HT_PARAM_CHA_SEC_ABOVE * NL80211_CHAN_HT40MINUS -> IEEE80211_HT_PARAM_CHA_SEC_BELOW * Others -> IEEE80211_HT_PARAM_CHA_SEC_NONE
*/
u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type)
{ switch (chan_type) { case NL80211_CHAN_NO_HT: case NL80211_CHAN_HT20: return IEEE80211_HT_PARAM_CHA_SEC_NONE; case NL80211_CHAN_HT40PLUS: return IEEE80211_HT_PARAM_CHA_SEC_ABOVE; case NL80211_CHAN_HT40MINUS: return IEEE80211_HT_PARAM_CHA_SEC_BELOW; default: return IEEE80211_HT_PARAM_CHA_SEC_NONE;
}
}
/* This function maps IEEE HT secondary channel type to NL80211 channel type
*/
u8 mwifiex_get_chan_type(struct mwifiex_private *priv)
{ struct mwifiex_channel_band channel_band; int ret;
ret = mwifiex_get_chan_info(priv, &channel_band);
if (!ret) { switch (channel_band.band_config.chan_width) { case CHAN_BW_20MHZ: if (IS_11N_ENABLED(priv)) return NL80211_CHAN_HT20; else return NL80211_CHAN_NO_HT; case CHAN_BW_40MHZ: if (channel_band.band_config.chan2_offset ==
SEC_CHAN_ABOVE) return NL80211_CHAN_HT40PLUS; else return NL80211_CHAN_HT40MINUS; default: return NL80211_CHAN_HT20;
}
}
return NL80211_CHAN_HT20;
}
/* * This function checks whether WEP is set.
*/ staticint
mwifiex_is_alg_wep(u32 cipher)
{ switch (cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: return 1; default: break;
}
return 0;
}
/* * This function retrieves the private structure from kernel wiphy structure.
*/ staticvoid *mwifiex_cfg80211_get_adapter(struct wiphy *wiphy)
{ return (void *) (*(unsignedlong *) wiphy_priv(wiphy));
}
if (!buf || !len) {
mwifiex_dbg(priv->adapter, ERROR, "invalid buffer and length\n"); return -EFAULT;
}
mgmt = (conststruct ieee80211_mgmt *)buf; if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA &&
ieee80211_is_probe_resp(mgmt->frame_control)) { /* Since we support offload probe resp, we need to skip probe
* resp in AP or GO mode */
mwifiex_dbg(priv->adapter, INFO, "info: skip to send probe resp in AP or GO mode\n"); return 0;
}
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) { if (ieee80211_is_auth(mgmt->frame_control))
mwifiex_dbg(priv->adapter, MSG, "auth: send auth to %pM\n", mgmt->da); if (ieee80211_is_deauth(mgmt->frame_control))
mwifiex_dbg(priv->adapter, MSG, "auth: send deauth to %pM\n", mgmt->da); if (ieee80211_is_disassoc(mgmt->frame_control))
mwifiex_dbg(priv->adapter, MSG, "assoc: send disassoc to %pM\n", mgmt->da); if (ieee80211_is_assoc_resp(mgmt->frame_control))
mwifiex_dbg(priv->adapter, MSG, "assoc: send assoc resp to %pM\n",
mgmt->da); if (ieee80211_is_reassoc_resp(mgmt->frame_control))
mwifiex_dbg(priv->adapter, MSG, "assoc: send reassoc resp to %pM\n",
mgmt->da);
}
/* * CFG802.11 operation handler to get Tx power.
*/ staticint
mwifiex_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, int radio_idx, unsignedint link_id, int *dbm)
{ struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); struct mwifiex_private *priv = mwifiex_get_priv(adapter,
MWIFIEX_BSS_ROLE_ANY); int ret = mwifiex_send_cmd(priv, HostCmd_CMD_RF_TX_PWR,
HostCmd_ACT_GEN_GET, 0, NULL, true);
if (ret < 0) return ret;
/* tx_power_level is set in HostCmd_CMD_RF_TX_PWR command handler */
*dbm = priv->tx_power_level;
return 0;
}
/* * CFG802.11 operation handler to set Power Save option. * * The timeout value, if provided, is currently ignored.
*/ staticint
mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout)
{ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
u32 ps_mode;
if (timeout)
mwifiex_dbg(priv->adapter, INFO, "info: ignore timeout value for IEEE Power Save\n");
ps_mode = enabled;
return mwifiex_drv_set_power(priv, &ps_mode);
}
/* * CFG802.11 operation handler to set the default network key.
*/ staticint
mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev, int link_id, u8 key_index, bool unicast, bool multicast)
{ struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
/* Return if WEP key not configured */ if (!priv->sec_info.wep_enabled) return 0;
/* * This function sends domain information to the firmware. * * The following information are passed to the firmware - * - Country codes * - Sub bands (first channel, number of channels, maximum Tx power)
*/ int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
{
u8 no_of_triplet = 0; struct ieee80211_country_ie_triplet *t;
u8 no_of_parsed_chan = 0;
u8 first_chan = 0, next_chan = 0, max_pwr = 0;
u8 i, flag = 0; enum nl80211_band band; struct ieee80211_supported_band *sband; struct ieee80211_channel *ch; struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); struct mwifiex_private *priv; struct mwifiex_802_11d_domain_reg *domain_info = &adapter->domain_reg;
/* Set country code */
domain_info->country_code[0] = adapter->country_code[0];
domain_info->country_code[1] = adapter->country_code[1];
domain_info->country_code[2] = ' ';
band = mwifiex_band_to_radio_type(adapter->config_bands); if (!wiphy->bands[band]) {
mwifiex_dbg(adapter, ERROR, "11D: setting domain info in FW\n"); return -1;
}
sband = wiphy->bands[band];
for (i = 0; i < sband->n_channels ; i++) {
ch = &sband->channels[i]; if (ch->flags & IEEE80211_CHAN_DISABLED) continue;
if (!wiphy->bands[NL80211_BAND_5GHZ]) return;
sband = wiphy->bands[NL80211_BAND_5GHZ];
for (i = 0; i < sband->n_channels; i++) {
chan = &sband->channels[i]; if ((!(chan->flags & IEEE80211_CHAN_DISABLED)) &&
(chan->flags & IEEE80211_CHAN_RADAR))
chan->flags |= IEEE80211_CHAN_NO_IR;
}
}
/* * CFG802.11 regulatory domain callback function. * * This function is called when the regulatory domain is changed due to the * following reasons - * - Set by driver * - Set by system core * - Set by user * - Set bt Country IE
*/ staticvoid mwifiex_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
{ struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); struct mwifiex_private *priv = mwifiex_get_priv(adapter,
MWIFIEX_BSS_ROLE_ANY);
mwifiex_dbg(adapter, INFO, "info: cfg80211 regulatory domain callback for %c%c\n",
request->alpha2[0], request->alpha2[1]);
mwifiex_reg_apply_radar_flags(wiphy);
switch (request->initiator) { case NL80211_REGDOM_SET_BY_DRIVER: case NL80211_REGDOM_SET_BY_CORE: case NL80211_REGDOM_SET_BY_USER: case NL80211_REGDOM_SET_BY_COUNTRY_IE: break; default:
mwifiex_dbg(adapter, ERROR, "unknown regdom initiator: %d\n",
request->initiator); return;
}
/* Don't send same regdom info to firmware */ if (strncmp(request->alpha2, adapter->country_code, sizeof(request->alpha2)) != 0) {
memcpy(adapter->country_code, request->alpha2, sizeof(request->alpha2));
mwifiex_send_domain_info_cmd_fw(wiphy);
mwifiex_dnld_txpwr_table(priv);
}
}
/* * This function sets the fragmentation threshold. * * The fragmentation threshold value must lie between MWIFIEX_FRAG_MIN_VALUE * and MWIFIEX_FRAG_MAX_VALUE.
*/ staticint
mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr)
{ if (frag_thr < MWIFIEX_FRAG_MIN_VALUE ||
frag_thr > MWIFIEX_FRAG_MAX_VALUE)
frag_thr = MWIFIEX_FRAG_MAX_VALUE;
* The rts value must lie between MWIFIEX_RTS_MIN_VALUE * and MWIFIEX_RTS_MAX_VALUE.
*/ staticint
mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr)
{ if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE)
rts_thr = MWIFIEX_RTS_MAX_VALUE;
/* * CFG802.11 operation handler to set wiphy parameters. * * This function can be used to set the RTS threshold and the * Fragmentation threshold of the driver.
*/ staticint
mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx,
u32 changed)
{ struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); struct mwifiex_private *priv; struct mwifiex_uap_bss_param *bss_cfg; int ret;
/* * This function initializes the functionalities for P2P GO. * The P2P GO initialization sequence is: * disable -> device -> GO
*/ staticint
mwifiex_cfg80211_init_p2p_go(struct mwifiex_private *priv)
{
u16 mode;
staticbool
is_vif_type_change_allowed(struct mwifiex_adapter *adapter, enum nl80211_iftype old_iftype, enum nl80211_iftype new_iftype)
{ switch (old_iftype) { case NL80211_IFTYPE_ADHOC: switch (new_iftype) { case NL80211_IFTYPE_STATION: returntrue; case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_P2P_GO: return adapter->curr_iface_comb.p2p_intf !=
adapter->iface_limit.p2p_intf; case NL80211_IFTYPE_AP: return adapter->curr_iface_comb.uap_intf !=
adapter->iface_limit.uap_intf; default: returnfalse;
}
case NL80211_IFTYPE_STATION: switch (new_iftype) { case NL80211_IFTYPE_ADHOC: returntrue; case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_P2P_GO: return adapter->curr_iface_comb.p2p_intf !=
adapter->iface_limit.p2p_intf; case NL80211_IFTYPE_AP: return adapter->curr_iface_comb.uap_intf !=
adapter->iface_limit.uap_intf; default: returnfalse;
}
case NL80211_IFTYPE_AP: switch (new_iftype) { case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_STATION: return adapter->curr_iface_comb.sta_intf !=
adapter->iface_limit.sta_intf; case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_P2P_GO: return adapter->curr_iface_comb.p2p_intf !=
adapter->iface_limit.p2p_intf; default: returnfalse;
}
case NL80211_IFTYPE_P2P_CLIENT: switch (new_iftype) { case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_STATION: returntrue; case NL80211_IFTYPE_P2P_GO: returntrue; case NL80211_IFTYPE_AP: return adapter->curr_iface_comb.uap_intf !=
adapter->iface_limit.uap_intf; default: returnfalse;
}
case NL80211_IFTYPE_P2P_GO: switch (new_iftype) { case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_STATION: returntrue; case NL80211_IFTYPE_P2P_CLIENT: returntrue; case NL80211_IFTYPE_AP: return adapter->curr_iface_comb.uap_intf !=
adapter->iface_limit.uap_intf; default: returnfalse;
}
default: break;
}
returnfalse;
}
staticvoid
update_vif_type_counter(struct mwifiex_adapter *adapter, enum nl80211_iftype iftype, int change)
{ switch (iftype) { case NL80211_IFTYPE_UNSPECIFIED: case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_STATION:
adapter->curr_iface_comb.sta_intf += change; break; case NL80211_IFTYPE_AP:
adapter->curr_iface_comb.uap_intf += change; break; case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_P2P_GO:
adapter->curr_iface_comb.p2p_intf += change; break; default:
mwifiex_dbg(adapter, ERROR, "%s: Unsupported iftype passed: %d\n",
__func__, iftype); break;
}
}
if (type == NL80211_IFTYPE_STATION)
mwifiex_dbg(adapter, INFO, "%s: changing role to station\n", dev->name); else
mwifiex_dbg(adapter, INFO, "%s: changing role to adhoc\n", dev->name);
if (mwifiex_deinit_priv_params(priv)) return -1; if (mwifiex_init_new_priv_params(priv, dev, type)) return -1;
if (priv->scan_request) {
mwifiex_dbg(priv->adapter, ERROR, "change virtual interface: scan in process\n"); return -EBUSY;
}
if (type == NL80211_IFTYPE_UNSPECIFIED) {
mwifiex_dbg(priv->adapter, INFO, "%s: no new type specified, keeping old type %d\n",
dev->name, curr_iftype); return 0;
}
if (curr_iftype == type) {
mwifiex_dbg(priv->adapter, INFO, "%s: interface already is of type %d\n",
dev->name, curr_iftype); return 0;
}
if (!is_vif_type_change_allowed(priv->adapter, curr_iftype, type)) {
mwifiex_dbg(priv->adapter, ERROR, "%s: change from type %d to %d is not allowed\n",
dev->name, curr_iftype, type); return -EOPNOTSUPP;
}
switch (curr_iftype) { case NL80211_IFTYPE_ADHOC: switch (type) { case NL80211_IFTYPE_STATION:
priv->bss_mode = type;
priv->sec_info.authentication_mode =
NL80211_AUTHTYPE_OPEN_SYSTEM;
dev->ieee80211_ptr->iftype = type;
mwifiex_deauthenticate(priv, NULL); return mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
HostCmd_ACT_GEN_SET, 0, NULL, true); case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_P2P_GO: return mwifiex_change_vif_to_p2p(dev, curr_iftype,
type, params); case NL80211_IFTYPE_AP: return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
params); default: goto errnotsupp;
}
case NL80211_IFTYPE_STATION: switch (type) { case NL80211_IFTYPE_ADHOC:
priv->bss_mode = type;
priv->sec_info.authentication_mode =
NL80211_AUTHTYPE_OPEN_SYSTEM;
dev->ieee80211_ptr->iftype = type;
mwifiex_deauthenticate(priv, NULL); return mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
HostCmd_ACT_GEN_SET, 0, NULL, true); case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_P2P_GO: return mwifiex_change_vif_to_p2p(dev, curr_iftype,
type, params); case NL80211_IFTYPE_AP: return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
params); default: goto errnotsupp;
}
case NL80211_IFTYPE_AP: switch (type) { case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_STATION: return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,
type, params); break; case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_P2P_GO: return mwifiex_change_vif_to_p2p(dev, curr_iftype,
type, params); default: goto errnotsupp;
}
case NL80211_IFTYPE_P2P_CLIENT: if (mwifiex_cfg80211_deinit_p2p(priv)) return -EFAULT;
switch (type) { case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_STATION: return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,
type, params); case NL80211_IFTYPE_P2P_GO: return mwifiex_change_vif_to_p2p(dev, curr_iftype,
type, params); case NL80211_IFTYPE_AP: return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
params); default: goto errnotsupp;
}
case NL80211_IFTYPE_P2P_GO: if (mwifiex_cfg80211_deinit_p2p(priv)) return -EFAULT;
switch (type) { case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_STATION: return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,
type, params); case NL80211_IFTYPE_P2P_CLIENT: return mwifiex_change_vif_to_p2p(dev, curr_iftype,
type, params); case NL80211_IFTYPE_AP: return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
params); default: goto errnotsupp;
}
default: goto errnotsupp;
}
return 0;
errnotsupp:
mwifiex_dbg(priv->adapter, ERROR, "unsupported interface type transition: %d to %d\n",
curr_iftype, type); return -EOPNOTSUPP;
}
/* * This function dumps the station information on a buffer. * * The following information are shown - * - Total bytes transmitted * - Total bytes received * - Total packets transmitted * - Total packets received * - Signal quality level * - Transmission rate
*/ staticint
mwifiex_dump_station_info(struct mwifiex_private *priv, struct mwifiex_sta_node *node, struct station_info *sinfo)
{
u32 rate;
/* Get signal information from the firmware */ if (mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
HostCmd_ACT_GEN_GET, 0, NULL, true)) {
mwifiex_dbg(priv->adapter, ERROR, "failed to get signal information\n"); return -EFAULT;
}
if (mwifiex_drv_get_data_rate(priv, &rate)) {
mwifiex_dbg(priv->adapter, ERROR, "getting data rate error\n"); return -EFAULT;
}
/* Get DTIM period information from firmware */
mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
HostCmd_ACT_GEN_GET, DTIM_PERIOD_I,
&priv->dtim_period, true);
/* * CFG802.11 operation handler to get station information. * * This function only works in connected mode, and dumps the * requested station information, if available.
*/ staticint
mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac, struct station_info *sinfo)
{ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
if (!priv->media_connected) return -ENOENT; if (memcmp(mac, priv->cfg_bssid, ETH_ALEN)) return -ENOENT;
/* cfg80211 operation handler for del_station. * Function deauthenticates station which value is provided in mac parameter. * If mac is NULL/broadcast, all stations in associated station list are * deauthenticated. If bss is not started or there are no stations in * associated stations list, no action is taken.
*/ staticint
mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, struct station_del_parameters *params)
{ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); struct mwifiex_sta_node *sta_node;
u8 deauth_mac[ETH_ALEN];
if (adapter->hw_dev_mcs_support != HT_STREAM_2X2) { /* Not a MIMO chip. User should provide specific antenna number * for Tx/Rx path or enable all antennas for diversity
*/ if (tx_ant != rx_ant) return -EOPNOTSUPP;
if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
HostCmd_ACT_GEN_SET, 0, NULL, true)) {
mwifiex_dbg(priv->adapter, ERROR, "Failed to stop the BSS\n"); return -1;
}
if (mwifiex_send_cmd(priv, HOST_CMD_APCMD_SYS_RESET,
HostCmd_ACT_GEN_SET, 0, NULL, true)) {
mwifiex_dbg(priv->adapter, ERROR, "Failed to reset BSS\n"); return -1;
}
if (netif_carrier_ok(priv->netdev))
netif_carrier_off(priv->netdev);
mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
return 0;
}
/* cfg80211 operation handler for start_ap. * Function sets beacon period, DTIM period, SSID and security into * AP config structure. * AP is configured with these settings and BSS is started.
*/ staticint mwifiex_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *params)
{ struct mwifiex_uap_bss_param *bss_cfg; struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP) return -1;
bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL); if (!bss_cfg) return -ENOMEM;
/* * CFG802.11 operation handler for disconnection request. * * This function does not work when there is already a disconnection * procedure going on.
*/ staticint
mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
u16 reason_code)
{ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
if (!mwifiex_stop_bg_scan(priv))
cfg80211_sched_scan_stopped_locked(priv->wdev.wiphy, 0);
if (mwifiex_deauthenticate(priv, NULL)) return -EFAULT;
/* * This function informs the CFG802.11 subsystem of a new IBSS. * * The following information are sent to the CFG802.11 subsystem * to register the new IBSS. If we do not register the new IBSS, * a kernel panic will result. * - SSID * - SSID length * - BSSID * - Channel
*/ staticint mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
{ struct ieee80211_channel *chan; struct mwifiex_bss_info bss_info; struct cfg80211_bss *bss; int ie_len;
u8 ie_buf[IEEE80211_MAX_SSID_LEN + sizeof(struct ieee_types_header)]; enum nl80211_band band;
if (mwifiex_get_bss_info(priv, &bss_info)) return -1;
/* * This function connects with a BSS. * * This function handles both Infra and Ad-Hoc modes. It also performs * validity checking on the provided parameters, disconnects from the * current BSS (if any), sets up the association/scan parameters, * including security settings, and performs specific SSID scan before * trying to connect. * * For Infra mode, the function returns failure if the specified SSID * is not found in scan table. However, for Ad-Hoc mode, it can create * the IBSS if it does not exist. On successful completion in either case, * the function notifies the CFG802.11 subsystem of the new BSS connection.
*/ staticint
mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, const u8 *ssid, const u8 *bssid, int mode, struct ieee80211_channel *channel, struct cfg80211_connect_params *sme, bool privacy, struct cfg80211_bss **sel_bss)
{ struct cfg80211_ssid req_ssid; int ret, auth_type = 0; struct cfg80211_bss *bss = NULL;
u8 is_scanning_required = 0;
/* As this is new association, clear locally stored
* keys and security related flags */
priv->sec_info.wpa_enabled = false;
priv->sec_info.wpa2_enabled = false;
priv->wep_key_curr_index = 0;
priv->sec_info.encryption_mode = 0;
priv->sec_info.is_authtype_auto = 0;
ret = mwifiex_set_encode(priv, NULL, NULL, 0, 0, NULL, 1);
if (mode == NL80211_IFTYPE_ADHOC) {
u16 enable = true;
/* set ibss coalescing_status */
ret = mwifiex_send_cmd(
priv,
HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
HostCmd_ACT_GEN_SET, 0, &enable, true); if (ret) return ret;
/* "privacy" is set only for ad-hoc mode */ if (privacy) { /* * Keep WLAN_CIPHER_SUITE_WEP104 for now so that * the firmware can find a matching network from the * scan. The cfg80211 does not give us the encryption * mode at this stage so just setting it to WEP here.
*/
priv->sec_info.encryption_mode =
WLAN_CIPHER_SUITE_WEP104;
priv->sec_info.authentication_mode =
NL80211_AUTHTYPE_OPEN_SYSTEM;
}
goto done;
}
/* Now handle infra mode. "sme" is valid for infra mode only */ if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) {
auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
priv->sec_info.is_authtype_auto = 1;
} else {
auth_type = sme->auth_type;
}
if (sme->crypto.n_ciphers_pairwise) {
priv->sec_info.encryption_mode =
sme->crypto.ciphers_pairwise[0];
priv->sec_info.authentication_mode = auth_type;
}
if (sme->crypto.cipher_group) {
priv->sec_info.encryption_mode = sme->crypto.cipher_group;
priv->sec_info.authentication_mode = auth_type;
} if (sme->ie)
ret = mwifiex_set_gen_ie(priv, sme->ie, sme->ie_len);
if (sme->key) { if (mwifiex_is_alg_wep(priv->sec_info.encryption_mode)) {
mwifiex_dbg(priv->adapter, INFO, "info: setting wep encryption\t" "with key len %d\n", sme->key_len);
priv->wep_key_curr_index = sme->key_idx;
ret = mwifiex_set_encode(priv, NULL, sme->key,
sme->key_len, sme->key_idx,
NULL, 0);
}
}
done: /* * Scan entries are valid for some time (15 sec). So we can save one * active scan time if we just try cfg80211_get_bss first. If it fails * then request scan and cfg80211_get_bss() again for final output.
*/ while (1) { if (is_scanning_required) { /* Do specific SSID scanning */ if (mwifiex_request_scan(priv, &req_ssid)) {
mwifiex_dbg(priv->adapter, ERROR, "scan error\n"); return -EFAULT;
}
}
/* Find the BSS we want using available scan results */ if (mode == NL80211_IFTYPE_ADHOC)
bss = cfg80211_get_bss(priv->wdev.wiphy, channel,
bssid, ssid, ssid_len,
IEEE80211_BSS_TYPE_IBSS,
IEEE80211_PRIVACY_ANY); else
bss = cfg80211_get_bss(priv->wdev.wiphy, channel,
bssid, ssid, ssid_len,
IEEE80211_BSS_TYPE_ESS,
IEEE80211_PRIVACY_ANY);
if (!bss) { if (is_scanning_required) {
mwifiex_dbg(priv->adapter, MSG, "assoc: requested bss not found in scan results\n"); break;
}
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5
¤ Dauer der Verarbeitung: 0.43 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.