mac80211: unify config_interface and bss_info_changed

The config_interface method is a little strange, it contains the
BSSID and beacon updates, while bss_info_changed contains most
other BSS information for each interface. This patch removes
config_interface and rolls all the information it previously
passed to drivers into bss_info_changed.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
这个提交包含在:
Johannes Berg
2009-04-23 16:13:26 +02:00
提交者 John W. Linville
父节点 57c4d7b4c4
当前提交 2d0ddec5b2
修改 34 个文件,包含 504 行新增778 行删除

查看文件

@@ -1360,33 +1360,6 @@ out:
return err;
}
static int ar9170_op_config_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_if_conf *conf)
{
struct ar9170 *ar = hw->priv;
int err = 0;
mutex_lock(&ar->mutex);
if (conf->changed & IEEE80211_IFCC_BSSID) {
memcpy(ar->bssid, conf->bssid, ETH_ALEN);
err = ar9170_set_operating_mode(ar);
}
if (conf->changed & IEEE80211_IFCC_BEACON) {
err = ar9170_update_beacon(ar);
if (err)
goto out;
err = ar9170_set_beacon_timers(ar);
}
out:
mutex_unlock(&ar->mutex);
return err;
}
static void ar9170_set_filters(struct work_struct *work)
{
struct ar9170 *ar = container_of(work, struct ar9170,
@@ -1488,6 +1461,17 @@ static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
mutex_lock(&ar->mutex);
if (changed & BSS_CHANGED_BSSID) {
memcpy(ar->bssid, bss_conf->bssid, ETH_ALEN);
err = ar9170_set_operating_mode(ar);
}
if (changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) {
err = ar9170_update_beacon(ar);
if (!err)
ar9170_set_beacon_timers(ar);
}
ar9170_regwrite_begin(ar);
if (changed & BSS_CHANGED_ASSOC) {
@@ -1796,7 +1780,6 @@ static const struct ieee80211_ops ar9170_ops = {
.add_interface = ar9170_op_add_interface,
.remove_interface = ar9170_op_remove_interface,
.config = ar9170_op_config,
.config_interface = ar9170_op_config_interface,
.configure_filter = ar9170_op_configure_filter,
.conf_tx = ar9170_conf_tx,
.bss_info_changed = ar9170_op_bss_info_changed,

查看文件

@@ -227,9 +227,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
static void ath5k_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf);
static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
static int ath5k_config_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_if_conf *conf);
static void ath5k_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
unsigned int *new_flags,
@@ -259,7 +256,6 @@ static const struct ieee80211_ops ath5k_hw_ops = {
.add_interface = ath5k_add_interface,
.remove_interface = ath5k_remove_interface,
.config = ath5k_config,
.config_interface = ath5k_config_interface,
.configure_filter = ath5k_configure_filter,
.set_key = ath5k_set_key,
.get_stats = ath5k_get_stats,
@@ -2764,44 +2760,6 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
return ret;
}
static int
ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_if_conf *conf)
{
struct ath5k_softc *sc = hw->priv;
struct ath5k_hw *ah = sc->ah;
int ret = 0;
mutex_lock(&sc->lock);
if (sc->vif != vif) {
ret = -EIO;
goto unlock;
}
if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
/* Cache for later use during resets */
memcpy(ah->ah_bssid, conf->bssid, ETH_ALEN);
/* XXX: assoc id is set to 0 for now, mac80211 doesn't have
* a clean way of letting us retrieve this yet. */
ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
mmiowb();
}
if (conf->changed & IEEE80211_IFCC_BEACON &&
(vif->type == NL80211_IFTYPE_ADHOC ||
vif->type == NL80211_IFTYPE_MESH_POINT ||
vif->type == NL80211_IFTYPE_AP)) {
struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
if (!beacon) {
ret = -ENOMEM;
goto unlock;
}
ath5k_beacon_update(sc, beacon);
}
unlock:
mutex_unlock(&sc->lock);
return ret;
}
#define SUPPORTED_FIF_FLAGS \
FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \
FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \
@@ -3082,15 +3040,40 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
u32 changes)
{
struct ath5k_softc *sc = hw->priv;
struct ath5k_hw *ah = sc->ah;
mutex_lock(&sc->lock);
if (WARN_ON(sc->vif != vif))
goto unlock;
if (changes & BSS_CHANGED_BSSID) {
/* Cache for later use during resets */
memcpy(ah->ah_bssid, bss_conf->bssid, ETH_ALEN);
/* XXX: assoc id is set to 0 for now, mac80211 doesn't have
* a clean way of letting us retrieve this yet. */
ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
mmiowb();
}
if (changes & BSS_CHANGED_BEACON_INT)
sc->bintval = bss_conf->beacon_int;
if (changes & BSS_CHANGED_ASSOC) {
mutex_lock(&sc->lock);
sc->assoc = bss_conf->assoc;
if (sc->opmode == NL80211_IFTYPE_STATION)
set_beacon_filter(hw, sc->assoc);
mutex_unlock(&sc->lock);
}
if (changes & BSS_CHANGED_BEACON &&
(vif->type == NL80211_IFTYPE_ADHOC ||
vif->type == NL80211_IFTYPE_MESH_POINT ||
vif->type == NL80211_IFTYPE_AP)) {
struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
if (beacon)
ath5k_beacon_update(sc, beacon);
}
unlock:
mutex_unlock(&sc->lock);
}

查看文件

@@ -2363,104 +2363,6 @@ skip_chan_change:
return 0;
}
static int ath9k_config_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_if_conf *conf)
{
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
struct ath_hw *ah = sc->sc_ah;
struct ath_vif *avp = (void *)vif->drv_priv;
u32 rfilt = 0;
int error, i;
mutex_lock(&sc->mutex);
/* TODO: Need to decide which hw opmode to use for multi-interface
* cases */
if (vif->type == NL80211_IFTYPE_AP &&
ah->opmode != NL80211_IFTYPE_AP) {
ah->opmode = NL80211_IFTYPE_STATION;
ath9k_hw_setopmode(ah);
memcpy(sc->curbssid, sc->sc_ah->macaddr, ETH_ALEN);
sc->curaid = 0;
ath9k_hw_write_associd(sc);
/* Request full reset to get hw opmode changed properly */
sc->sc_flags |= SC_OP_FULL_RESET;
}
if ((conf->changed & IEEE80211_IFCC_BSSID) &&
!is_zero_ether_addr(conf->bssid)) {
switch (vif->type) {
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_MESH_POINT:
/* Set BSSID */
memcpy(sc->curbssid, conf->bssid, ETH_ALEN);
memcpy(avp->bssid, conf->bssid, ETH_ALEN);
sc->curaid = 0;
ath9k_hw_write_associd(sc);
/* Set aggregation protection mode parameters */
sc->config.ath_aggr_prot = 0;
DPRINTF(sc, ATH_DBG_CONFIG,
"RX filter 0x%x bssid %pM aid 0x%x\n",
rfilt, sc->curbssid, sc->curaid);
/* need to reconfigure the beacon */
sc->sc_flags &= ~SC_OP_BEACONS ;
break;
default:
break;
}
}
if ((vif->type == NL80211_IFTYPE_ADHOC) ||
(vif->type == NL80211_IFTYPE_AP) ||
(vif->type == NL80211_IFTYPE_MESH_POINT)) {
if ((conf->changed & IEEE80211_IFCC_BEACON) ||
(conf->changed & IEEE80211_IFCC_BEACON_ENABLED &&
conf->enable_beacon)) {
/*
* Allocate and setup the beacon frame.
*
* Stop any previous beacon DMA. This may be
* necessary, for example, when an ibss merge
* causes reconfiguration; we may be called
* with beacon transmission active.
*/
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
error = ath_beacon_alloc(aphy, vif);
if (error != 0) {
mutex_unlock(&sc->mutex);
return error;
}
ath_beacon_config(sc, vif);
}
}
/* Check for WLAN_CAPABILITY_PRIVACY ? */
if ((avp->av_opmode != NL80211_IFTYPE_STATION)) {
for (i = 0; i < IEEE80211_WEP_NKID; i++)
if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
ath9k_hw_keysetmac(sc->sc_ah,
(u16)i,
sc->curbssid);
}
/* Only legacy IBSS for now */
if (vif->type == NL80211_IFTYPE_ADHOC)
ath_update_chainmask(sc, 0);
mutex_unlock(&sc->mutex);
return 0;
}
#define SUPPORTED_FILTERS \
(FIF_PROMISC_IN_BSS | \
FIF_ALLMULTI | \
@@ -2597,9 +2499,92 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
{
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
struct ath_hw *ah = sc->sc_ah;
struct ath_vif *avp = (void *)vif->drv_priv;
u32 rfilt = 0;
int error, i;
mutex_lock(&sc->mutex);
/*
* TODO: Need to decide which hw opmode to use for
* multi-interface cases
* XXX: This belongs into add_interface!
*/
if (vif->type == NL80211_IFTYPE_AP &&
ah->opmode != NL80211_IFTYPE_AP) {
ah->opmode = NL80211_IFTYPE_STATION;
ath9k_hw_setopmode(ah);
memcpy(sc->curbssid, sc->sc_ah->macaddr, ETH_ALEN);
sc->curaid = 0;
ath9k_hw_write_associd(sc);
/* Request full reset to get hw opmode changed properly */
sc->sc_flags |= SC_OP_FULL_RESET;
}
if ((changed & BSS_CHANGED_BSSID) &&
!is_zero_ether_addr(bss_conf->bssid)) {
switch (vif->type) {
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_MESH_POINT:
/* Set BSSID */
memcpy(sc->curbssid, bss_conf->bssid, ETH_ALEN);
memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN);
sc->curaid = 0;
ath9k_hw_write_associd(sc);
/* Set aggregation protection mode parameters */
sc->config.ath_aggr_prot = 0;
DPRINTF(sc, ATH_DBG_CONFIG,
"RX filter 0x%x bssid %pM aid 0x%x\n",
rfilt, sc->curbssid, sc->curaid);
/* need to reconfigure the beacon */
sc->sc_flags &= ~SC_OP_BEACONS ;
break;
default:
break;
}
}
if ((vif->type == NL80211_IFTYPE_ADHOC) ||
(vif->type == NL80211_IFTYPE_AP) ||
(vif->type == NL80211_IFTYPE_MESH_POINT)) {
if ((changed & BSS_CHANGED_BEACON) ||
(changed & BSS_CHANGED_BEACON_ENABLED &&
bss_conf->enable_beacon)) {
/*
* Allocate and setup the beacon frame.
*
* Stop any previous beacon DMA. This may be
* necessary, for example, when an ibss merge
* causes reconfiguration; we may be called
* with beacon transmission active.
*/
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
error = ath_beacon_alloc(aphy, vif);
if (!error)
ath_beacon_config(sc, vif);
}
}
/* Check for WLAN_CAPABILITY_PRIVACY ? */
if ((avp->av_opmode != NL80211_IFTYPE_STATION)) {
for (i = 0; i < IEEE80211_WEP_NKID; i++)
if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
ath9k_hw_keysetmac(sc->sc_ah,
(u16)i,
sc->curbssid);
}
/* Only legacy IBSS for now */
if (vif->type == NL80211_IFTYPE_ADHOC)
ath_update_chainmask(sc, 0);
if (changed & BSS_CHANGED_ERP_PREAMBLE) {
DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
bss_conf->use_short_preamble);
@@ -2757,7 +2742,6 @@ struct ieee80211_ops ath9k_ops = {
.add_interface = ath9k_add_interface,
.remove_interface = ath9k_remove_interface,
.config = ath9k_config,
.config_interface = ath9k_config_interface,
.configure_filter = ath9k_configure_filter,
.sta_notify = ath9k_sta_notify,
.conf_tx = ath9k_conf_tx,