Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2d0ddec5 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

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: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 57c4d7b4
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -1311,18 +1311,20 @@ static int adm8211_config(struct ieee80211_hw *dev, u32 changed)
	return 0;
}

static int adm8211_config_interface(struct ieee80211_hw *dev,
static void adm8211_bss_info_changed(struct ieee80211_hw *dev,
				     struct ieee80211_vif *vif,
				    struct ieee80211_if_conf *conf)
				     struct ieee80211_bss_conf *conf,
				     u32 changes)
{
	struct adm8211_priv *priv = dev->priv;

	if (!(changes & BSS_CHANGED_BSSID))
		return;

	if (memcmp(conf->bssid, priv->bssid, ETH_ALEN)) {
		adm8211_set_bssid(dev, conf->bssid);
		memcpy(priv->bssid, conf->bssid, ETH_ALEN);
	}

	return 0;
}

static void adm8211_configure_filter(struct ieee80211_hw *dev,
@@ -1753,7 +1755,7 @@ static const struct ieee80211_ops adm8211_ops = {
	.add_interface		= adm8211_add_interface,
	.remove_interface	= adm8211_remove_interface,
	.config			= adm8211_config,
	.config_interface	= adm8211_config_interface,
	.bss_info_changed	= adm8211_bss_info_changed,
	.configure_filter	= adm8211_configure_filter,
	.get_stats		= adm8211_get_stats,
	.get_tx_stats		= adm8211_get_tx_stats,
+9 −6
Original line number Diff line number Diff line
@@ -1965,13 +1965,18 @@ static int at76_config(struct ieee80211_hw *hw, u32 changed)
	return 0;
}

static int at76_config_interface(struct ieee80211_hw *hw,
static void at76_bss_info_changed(struct ieee80211_hw *hw,
				  struct ieee80211_vif *vif,
				 struct ieee80211_if_conf *conf)
				  struct ieee80211_bss_conf *conf,
				  u32 changed)
{
	struct at76_priv *priv = hw->priv;

	at76_dbg(DBG_MAC80211, "%s():", __func__);

	if (!(changed & BSS_CHANGED_BSSID))
		return;

	at76_dbg_dump(DBG_MAC80211, conf->bssid, ETH_ALEN, "bssid:");

	mutex_lock(&priv->mtx);
@@ -1983,8 +1988,6 @@ static int at76_config_interface(struct ieee80211_hw *hw,
		at76_join(priv);

	mutex_unlock(&priv->mtx);

	return 0;
}

/* must be atomic */
@@ -2076,7 +2079,7 @@ static const struct ieee80211_ops at76_ops = {
	.add_interface = at76_add_interface,
	.remove_interface = at76_remove_interface,
	.config = at76_config,
	.config_interface = at76_config_interface,
	.bss_info_changed = at76_bss_info_changed,
	.configure_filter = at76_configure_filter,
	.start = at76_mac80211_start,
	.stop = at76_mac80211_stop,
+11 −28
Original line number Diff line number Diff line
@@ -1360,33 +1360,6 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
	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,
+27 −44
Original line number Diff line number Diff line
@@ -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);
}
+83 −99
Original line number Diff line number Diff line
@@ -2363,104 +2363,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
	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,
Loading