/* This function checks if current IE index is used by any on other interface. *Return:-1:yes,currentIEindexisusedbysomeoneelse. *0:no,currentIEindexisNOTusedbyotherinterface.
*/ staticint
mwifiex_ie_index_used_by_other_intf(struct mwifiex_private *priv, u16 idx)
{ int i; struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_ie *ie;
for (i = 0; i < adapter->priv_num; i++) { if (adapter->priv[i] != priv) {
ie = &adapter->priv[i]->mgmt_ie[idx]; if (ie->mgmt_subtype_mask && ie->ie_length) return -1;
}
}
return0;
}
/* Get unused IE index. This index will be used for setting new IE */ staticint
mwifiex_ie_get_autoidx(struct mwifiex_private *priv, u16 subtype_mask, struct mwifiex_ie *ie, u16 *index)
{
u16 mask, len, i;
for (i = 0; i < priv->adapter->max_mgmt_ie_index; i++) {
mask = le16_to_cpu(priv->mgmt_ie[i].mgmt_subtype_mask);
len = le16_to_cpu(ie->ie_length);
if (mask == MWIFIEX_AUTO_IDX_MASK) continue;
if (mask == subtype_mask) { if (len > IEEE_MAX_IE_SIZE) continue;
*index = i; return0;
}
if (!priv->mgmt_ie[i].ie_length) { if (mwifiex_ie_index_used_by_other_intf(priv, i)) continue;
*index = i; return0;
}
}
return -1;
}
/* This function prepares IE data buffer for command to be sent to FW */ staticint
mwifiex_update_autoindex_ies(struct mwifiex_private *priv, struct mwifiex_ie_list *ie_list)
{
u16 travel_len, index, mask;
s16 input_len, tlv_len; struct mwifiex_ie *ie;
u8 *tmp;
/* This function parses head and tail IEs, from cfg80211_beacon_data and sets *theseIEtoFW.
*/ staticint mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, struct cfg80211_beacon_data *info)
{ struct mwifiex_ie *gen_ie; struct ieee_types_header *hdr; struct ieee80211_vendor_ie *vendorhdr;
u16 gen_idx = MWIFIEX_AUTO_IDX_MASK, ie_len = 0; int left_len, parsed_len = 0; unsignedint token_len; int err = 0;
if (!info->tail || !info->tail_len) return0;
gen_ie = kzalloc(sizeof(*gen_ie), GFP_KERNEL); if (!gen_ie) return -ENOMEM;
left_len = info->tail_len;
/* Many IEs are generated in FW by parsing bss configuration. *Let'snotaddthemhere;elsewemayendupduplicatingtheseIEs
*/ while (left_len > sizeof(struct ieee_types_header)) {
hdr = (void *)(info->tail + parsed_len);
token_len = hdr->len + sizeof(struct ieee_types_header); if (token_len > left_len) {
err = -EINVAL; goto out;
}
switch (hdr->element_id) { case WLAN_EID_SSID: case WLAN_EID_SUPP_RATES: case WLAN_EID_COUNTRY: case WLAN_EID_PWR_CONSTRAINT: case WLAN_EID_ERP_INFO: case WLAN_EID_EXT_SUPP_RATES: case WLAN_EID_HT_CAPABILITY: case WLAN_EID_HT_OPERATION: case WLAN_EID_VHT_CAPABILITY: case WLAN_EID_VHT_OPERATION: break; case WLAN_EID_VENDOR_SPECIFIC: /* Skip only Microsoft WMM IE */ if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
WLAN_OUI_TYPE_MICROSOFT_WMM,
(const u8 *)hdr,
token_len)) break;
fallthrough; default: if (ie_len + token_len > IEEE_MAX_IE_SIZE) {
err = -EINVAL; goto out;
}
memcpy(gen_ie->ie_buffer + ie_len, hdr, token_len);
ie_len += token_len; break;
}
left_len -= token_len;
parsed_len += token_len;
}
/* parse only WPA vendor IE from tail, WMM IE is configured by *bss_configcommand
*/
vendorhdr = (void *)cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
WLAN_OUI_TYPE_MICROSOFT_WPA,
info->tail, info->tail_len); if (vendorhdr) {
token_len = vendorhdr->len + sizeof(struct ieee_types_header); if (ie_len + token_len > IEEE_MAX_IE_SIZE) {
err = -EINVAL; goto out;
}
memcpy(gen_ie->ie_buffer + ie_len, vendorhdr, token_len);
ie_len += token_len;
}
/* This function parses different IEs-head & tail IEs, beacon IEs, *proberesponseIEs,associationresponseIEsfromcfg80211_ap_settings *functionandsetstheseIEtoFW.
*/ int mwifiex_set_mgmt_ies(struct mwifiex_private *priv, struct cfg80211_beacon_data *info)
{ int ret;
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.