/* Don't allow other interfaces if one ad-hoc is configured. *TODO:Fixtheproblemswithad-hocandmultipleotherinterfaces. *WewouldneedtooperatetheHWinad-hocmodetoallowTSFupdates *fortheIBSS,butthisbreakswithadditionalAPorSTAinterfaces
* at the moment. */ if (ah->num_adhoc_vifs ||
(ah->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
ATH5K_ERR(ah, "Only one single ad-hoc interface is allowed.\n");
ret = -ELNRNG; goto end;
}
switch (vif->type) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_MESH_POINT:
avf->opmode = vif->type; break; default:
ret = -EOPNOTSUPP; goto end;
}
/* Assign the vap/adhoc to a beacon xmit slot. */ if ((avf->opmode == NL80211_IFTYPE_AP) ||
(avf->opmode == NL80211_IFTYPE_ADHOC) ||
(avf->opmode == NL80211_IFTYPE_MESH_POINT)) { int slot;
if (changes & BSS_CHANGED_BSSID) { /* Cache for later use during resets */
memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
common->curaid = 0;
ath5k_hw_set_bssid(ah);
}
if (changes & BSS_CHANGED_BEACON_INT)
ah->bintval = bss_conf->beacon_int;
if (changes & BSS_CHANGED_ERP_SLOT) { int slot_time;
if (changes & BSS_CHANGED_ASSOC) {
avf->assoc = vif->cfg.assoc; if (vif->cfg.assoc)
ah->assoc = vif->cfg.assoc; else
ah->assoc = ath5k_any_vif_assoc(ah);
if (ah->opmode == NL80211_IFTYPE_STATION)
ath5k_set_beacon_filter(hw, ah->assoc);
ath5k_hw_set_ledstate(ah, ah->assoc ?
AR5K_LED_ASSOC : AR5K_LED_INIT); if (vif->cfg.assoc) {
ATH5K_DBG(ah, ATH5K_DEBUG_ANY, "Bss Info ASSOC %d, bssid: %pM\n",
vif->cfg.aid, common->curbssid);
common->curaid = vif->cfg.aid;
ath5k_hw_set_bssid(ah); /* Once ANI is available you would start it here */
}
}
if (changes & BSS_CHANGED_BEACON) {
spin_lock_bh(&ah->block);
ath5k_beacon_update(hw, vif);
spin_unlock_bh(&ah->block);
}
if (changes & BSS_CHANGED_BEACON_ENABLED)
ah->enable_beacon = bss_conf->enable_beacon;
if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED |
BSS_CHANGED_BEACON_INT))
ath5k_beacon_config(ah);
struct ath5k_hw *ah = hw->priv;
u32 mfilt[2], rfilt; struct ath5k_vif_iter_data iter_data; /* to count STA interfaces */
mutex_lock(&ah->lock);
mfilt[0] = multicast;
mfilt[1] = multicast >> 32;
/* Only deal with supported flags */
*new_flags &= SUPPORTED_FIF_FLAGS;
/* If HW detects any phy or radar errors, leave those filters on. *Also,alwaysenableUnicast,BroadcastsandMulticast
* XXX: move unicast, bssid broadcasts and multicast to mac80211 */
rfilt = (ath5k_hw_get_rx_filter(ah) & (AR5K_RX_FILTER_PHYERR)) |
(AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST |
AR5K_RX_FILTER_MCAST);
/* Note, AR5K_RX_FILTER_MCAST is already enabled */ if (*new_flags & FIF_ALLMULTI) {
mfilt[0] = ~0;
mfilt[1] = ~0;
}
/* This is the best we can do */ if (*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL))
rfilt |= AR5K_RX_FILTER_PHYERR;
/* FIF_BCN_PRBRESP_PROMISC really means to enable beacons
* and probes for any BSSID */ if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (ah->nvifs > 1))
rfilt |= AR5K_RX_FILTER_BEACON;
/* FIF_CONTROL doc says we should only pass on control frames for this *station.Thisneedstesting.Ibelieverightnowthis *enables*all*controlframes,whichisOK..but
* we should see if we can improve on granularity */ if (*new_flags & FIF_CONTROL)
rfilt |= AR5K_RX_FILTER_CONTROL;
/* Additional settings per mode -- this is per ath5k */
/* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */
switch (ah->opmode) { case NL80211_IFTYPE_MESH_POINT:
rfilt |= AR5K_RX_FILTER_CONTROL |
AR5K_RX_FILTER_BEACON |
AR5K_RX_FILTER_PROBEREQ |
AR5K_RX_FILTER_PROM; break; case NL80211_IFTYPE_AP: case NL80211_IFTYPE_ADHOC:
rfilt |= AR5K_RX_FILTER_PROBEREQ |
AR5K_RX_FILTER_BEACON; break; case NL80211_IFTYPE_STATION: if (ah->assoc)
rfilt |= AR5K_RX_FILTER_BEACON; break; default: break;
}
/* Set up RX Filter */ if (iter_data.n_stas > 1) { /* If you have multiple STA interfaces connected to *differentAPs,ARPsarenotreceived(mostofthetime?) *EnablingPROMISCappearstofixthatproblem.
*/
rfilt |= AR5K_RX_FILTER_PROM;
}
/* Set filters */
ath5k_hw_set_rx_filter(ah, rfilt);
/* Set multicast bits */
ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]); /* Set the cached hw filter flags, this will later actually
* be set in HW */
ah->filter_flags = rfilt; /* Store current FIF filter flags */
ah->fif_filter_flags = *new_flags;
if (key->flags & IEEE80211_KEY_FLAG_RX_MGMT) return -EOPNOTSUPP;
if (vif->type == NL80211_IFTYPE_ADHOC &&
(key->cipher == WLAN_CIPHER_SUITE_TKIP ||
key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { /* don't program group keys when using IBSS_RSN */ return -EOPNOTSUPP;
}
switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: case WLAN_CIPHER_SUITE_TKIP: break; case WLAN_CIPHER_SUITE_CCMP: if (common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM) break; return -EOPNOTSUPP; default: return -EOPNOTSUPP;
}
mutex_lock(&ah->lock);
switch (cmd) { case SET_KEY:
ret = ath_key_config(common, vif, sta, key); if (ret >= 0) {
key->hw_key_idx = ret; /* push IV and Michael MIC generation to stack */
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; if (key->cipher == WLAN_CIPHER_SUITE_CCMP)
key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
ret = 0;
} break; case DISABLE_KEY:
ath_key_delete(common, key->hw_key_idx); break; default:
ret = -EINVAL;
}
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.