Skip to content

Commit

Permalink
mac80211: add unified BSS configuration
Browse files Browse the repository at this point in the history
This patch (based on Ron Rindjunsky's) creates a framework for
a unified way to pass BSS configuration to drivers that require
the information, e.g. for implementing power save mode.

This patch introduces new ieee80211_bss_conf structure that is
passed to the driver via the new bss_info_changed() callback
when the BSS configuration changes.

This new BSS configuration infrastructure adds the following
new features:
 * drivers are notified of their association AID
 * drivers are notified of association status

and replaces the erp_ie_changed() callback. The patch also does
the relevant driver updates for the latter change.

Signed-off-by: Ron Rindjunsky <ron.rindjunsky@intel.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Johannes Berg authored and David S. Miller committed Jan 28, 2008
1 parent 2bc454b commit 471b3ef
Show file tree
Hide file tree
Showing 19 changed files with 183 additions and 120 deletions.
6 changes: 2 additions & 4 deletions drivers/net/wireless/iwlwifi/iwl-3945.c
Original file line number Diff line number Diff line change
Expand Up @@ -520,10 +520,8 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
break;

/*
* TODO: There is no callback function from upper
* stack to inform us when associated status. this
* work around to sniff assoc_resp management frame
* and finish the association process.
* TODO: Use the new callback function from
* mac80211 instead of sniffing these packets.
*/
case IEEE80211_STYPE_ASSOC_RESP:
case IEEE80211_STYPE_REASSOC_RESP:{
Expand Down
6 changes: 2 additions & 4 deletions drivers/net/wireless/iwlwifi/iwl-4965.c
Original file line number Diff line number Diff line change
Expand Up @@ -4095,10 +4095,8 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
break;

/*
* TODO: There is no callback function from upper
* stack to inform us when associated status. this
* work around to sniff assoc_resp management frame
* and finish the association process.
* TODO: Use the new callback function from
* mac80211 instead of sniffing these packets.
*/
case IEEE80211_STYPE_ASSOC_RESP:
case IEEE80211_STYPE_REASSOC_RESP:
Expand Down
24 changes: 17 additions & 7 deletions drivers/net/wireless/iwlwifi/iwl4965-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -7764,25 +7764,35 @@ static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211("leave\n");

}
static void iwl4965_mac_erp_ie_changed(struct ieee80211_hw *hw,
u8 changes, int cts_protection, int preamble)

static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
u32 changes)
{
struct iwl4965_priv *priv = hw->priv;

if (changes & IEEE80211_ERP_CHANGE_PREAMBLE) {
if (preamble == WLAN_ERP_PREAMBLE_SHORT)
if (changes & BSS_CHANGED_ERP_PREAMBLE) {
if (bss_conf->use_short_preamble)
priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
}

if (changes & IEEE80211_ERP_CHANGE_PROTECTION) {
if (cts_protection && (priv->phymode != MODE_IEEE80211A))
if (changes & BSS_CHANGED_ERP_CTS_PROT) {
if (bss_conf->use_cts_prot && (priv->phymode != MODE_IEEE80211A))
priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
else
priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
}

if (changes & BSS_CHANGED_ASSOC) {
/*
* TODO:
* do stuff instead of sniffing assoc resp
*/
}

if (iwl4965_is_associated(priv))
iwl4965_send_rxon_assoc(priv);
}
Expand Down Expand Up @@ -8952,7 +8962,7 @@ static struct ieee80211_ops iwl4965_hw_ops = {
.get_tsf = iwl4965_mac_get_tsf,
.reset_tsf = iwl4965_mac_reset_tsf,
.beacon_update = iwl4965_mac_beacon_update,
.erp_ie_changed = iwl4965_mac_erp_ie_changed,
.bss_info_changed = iwl4965_bss_info_changed,
#ifdef CONFIG_IWL4965_HT
.conf_ht = iwl4965_mac_conf_ht,
.ampdu_action = iwl4965_mac_ampdu_action,
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/rt2x00/rt2400pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1524,7 +1524,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
.configure_filter = rt2400pci_configure_filter,
.get_stats = rt2x00mac_get_stats,
.set_retry_limit = rt2400pci_set_retry_limit,
.erp_ie_changed = rt2x00mac_erp_ie_changed,
.bss_info_changed = rt2x00mac_bss_info_changed,
.conf_tx = rt2400pci_conf_tx,
.get_tx_stats = rt2x00mac_get_tx_stats,
.get_tsf = rt2400pci_get_tsf,
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/rt2x00/rt2500pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1835,7 +1835,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
.configure_filter = rt2500pci_configure_filter,
.get_stats = rt2x00mac_get_stats,
.set_retry_limit = rt2500pci_set_retry_limit,
.erp_ie_changed = rt2x00mac_erp_ie_changed,
.bss_info_changed = rt2x00mac_bss_info_changed,
.conf_tx = rt2x00mac_conf_tx,
.get_tx_stats = rt2x00mac_get_tx_stats,
.get_tsf = rt2500pci_get_tsf,
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/rt2x00/rt2500usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1776,7 +1776,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
.config_interface = rt2x00mac_config_interface,
.configure_filter = rt2500usb_configure_filter,
.get_stats = rt2x00mac_get_stats,
.erp_ie_changed = rt2x00mac_erp_ie_changed,
.bss_info_changed = rt2x00mac_bss_info_changed,
.conf_tx = rt2x00mac_conf_tx,
.get_tx_stats = rt2x00mac_get_tx_stats,
.beacon_update = rt2500usb_beacon_update,
Expand Down
6 changes: 4 additions & 2 deletions drivers/net/wireless/rt2x00/rt2x00.h
Original file line number Diff line number Diff line change
Expand Up @@ -936,8 +936,10 @@ int rt2x00mac_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats);
int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw,
struct ieee80211_tx_queue_stats *stats);
void rt2x00mac_erp_ie_changed(struct ieee80211_hw *hw, u8 changes,
int cts_protection, int preamble);
void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
u32 changes);
int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue,
const struct ieee80211_tx_queue_params *params);

Expand Down
13 changes: 10 additions & 3 deletions drivers/net/wireless/rt2x00/rt2x00dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,10 +481,17 @@ static void rt2x00lib_configuration_scheduled(struct work_struct *work)
{
struct rt2x00_dev *rt2x00dev =
container_of(work, struct rt2x00_dev, config_work);
int preamble = !test_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags);
struct ieee80211_bss_conf bss_conf;

rt2x00mac_erp_ie_changed(rt2x00dev->hw,
IEEE80211_ERP_CHANGE_PREAMBLE, 0, preamble);
bss_conf.use_short_preamble =
test_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags);

/*
* FIXME: shouldn't invoke it this way because all other contents
* of bss_conf is invalid.
*/
rt2x00mac_bss_info_changed(rt2x00dev->hw, rt2x00dev->interface.id,
&bss_conf, BSS_CHANGED_ERP_PREAMBLE);
}

/*
Expand Down
16 changes: 10 additions & 6 deletions drivers/net/wireless/rt2x00/rt2x00mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,23 +342,27 @@ int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw,
}
EXPORT_SYMBOL_GPL(rt2x00mac_get_tx_stats);

void rt2x00mac_erp_ie_changed(struct ieee80211_hw *hw, u8 changes,
int cts_protection, int preamble)
void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
u32 changes)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
int short_preamble;
int ack_timeout;
int ack_consume_time;
int difs;
int preamble;

/*
* We only support changing preamble mode.
*/
if (!(changes & IEEE80211_ERP_CHANGE_PREAMBLE))
if (!(changes & BSS_CHANGED_ERP_PREAMBLE))
return;

short_preamble = !preamble;
preamble = !!(preamble) ? PREAMBLE : SHORT_PREAMBLE;
short_preamble = bss_conf->use_short_preamble;
preamble = bss_conf->use_short_preamble ?
SHORT_PREAMBLE : PREAMBLE;

difs = (hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) ?
SHORT_DIFS : DIFS;
Expand All @@ -374,7 +378,7 @@ void rt2x00mac_erp_ie_changed(struct ieee80211_hw *hw, u8 changes,
rt2x00dev->ops->lib->config_preamble(rt2x00dev, short_preamble,
ack_timeout, ack_consume_time);
}
EXPORT_SYMBOL_GPL(rt2x00mac_erp_ie_changed);
EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed);

int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue,
const struct ieee80211_tx_queue_params *params)
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/rt2x00/rt61pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -2441,7 +2441,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
.configure_filter = rt61pci_configure_filter,
.get_stats = rt2x00mac_get_stats,
.set_retry_limit = rt61pci_set_retry_limit,
.erp_ie_changed = rt2x00mac_erp_ie_changed,
.bss_info_changed = rt2x00mac_bss_info_changed,
.conf_tx = rt2x00mac_conf_tx,
.get_tx_stats = rt2x00mac_get_tx_stats,
.get_tsf = rt61pci_get_tsf,
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/rt2x00/rt73usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -2024,7 +2024,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
.configure_filter = rt73usb_configure_filter,
.get_stats = rt2x00mac_get_stats,
.set_retry_limit = rt73usb_set_retry_limit,
.erp_ie_changed = rt2x00mac_erp_ie_changed,
.bss_info_changed = rt2x00mac_bss_info_changed,
.conf_tx = rt2x00mac_conf_tx,
.get_tx_stats = rt2x00mac_get_tx_stats,
.get_tsf = rt73usb_get_tsf,
Expand Down
12 changes: 7 additions & 5 deletions drivers/net/wireless/zd1211rw/zd_mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -849,17 +849,19 @@ static void set_rts_cts_work(struct work_struct *work)
mutex_unlock(&mac->chip.mutex);
}

static void zd_op_erp_ie_changed(struct ieee80211_hw *hw, u8 changes,
int cts_protection, int preamble)
static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
u32 changes)
{
struct zd_mac *mac = zd_hw_mac(hw);
unsigned long flags;

dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes);

if (changes & IEEE80211_ERP_CHANGE_PREAMBLE) {
if (changes & BSS_CHANGED_ERP_PREAMBLE) {
spin_lock_irqsave(&mac->lock, flags);
mac->short_preamble = !preamble;
mac->short_preamble = bss_conf->use_short_preamble;
if (!mac->updating_rts_rate) {
mac->updating_rts_rate = 1;
/* FIXME: should disable TX here, until work has
Expand All @@ -879,7 +881,7 @@ static const struct ieee80211_ops zd_ops = {
.config = zd_op_config,
.config_interface = zd_op_config_interface,
.configure_filter = zd_op_configure_filter,
.erp_ie_changed = zd_op_erp_ie_changed,
.bss_info_changed = zd_op_bss_info_changed,
};

struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
Expand Down
66 changes: 49 additions & 17 deletions include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,43 @@ struct ieee80211_low_level_stats {
unsigned int dot11RTSSuccessCount;
};

/**
* enum ieee80211_bss_change - BSS change notification flags
*
* These flags are used with the bss_info_changed() callback
* to indicate which BSS parameter changed.
*
* @BSS_CHANGED_ASSOC: association status changed (associated/disassociated),
* also implies a change in the AID.
* @BSS_CHANGED_ERP_CTS_PROT: CTS protection changed
* @BSS_CHANGED_ERP_PREAMBLE: preamble changed
*/
enum ieee80211_bss_change {
BSS_CHANGED_ASSOC = 1<<0,
BSS_CHANGED_ERP_CTS_PROT = 1<<1,
BSS_CHANGED_ERP_PREAMBLE = 1<<2,
};

/**
* struct ieee80211_bss_conf - holds the BSS's changing parameters
*
* This structure keeps information about a BSS (and an association
* to that BSS) that can change during the lifetime of the BSS.
*
* @assoc: association status
* @aid: association ID number, valid only when @assoc is true
* @use_cts_prot: use CTS protection
* @use_short_preamble: use 802.11b short preamble
*/
struct ieee80211_bss_conf {
/* association related data */
bool assoc;
u16 aid;
/* erp related data */
bool use_cts_prot;
bool use_short_preamble;
};

/* Transmit control fields. This data structure is passed to low-level driver
* with each TX frame. The low-level driver is responsible for configuring
* the hardware to use given values (depending on what is supported). */
Expand Down Expand Up @@ -923,19 +960,6 @@ enum ieee80211_filter_flags {
FIF_OTHER_BSS = 1<<6,
};

/**
* enum ieee80211_erp_change_flags - erp change flags
*
* These flags are used with the erp_ie_changed() callback in
* &struct ieee80211_ops to indicate which parameter(s) changed.
* @IEEE80211_ERP_CHANGE_PROTECTION: protection changed
* @IEEE80211_ERP_CHANGE_PREAMBLE: barker preamble mode changed
*/
enum ieee80211_erp_change_flags {
IEEE80211_ERP_CHANGE_PROTECTION = 1<<0,
IEEE80211_ERP_CHANGE_PREAMBLE = 1<<1,
};

/**
* enum ieee80211_ampdu_mlme_action - A-MPDU actions
*
Expand Down Expand Up @@ -1004,6 +1028,14 @@ enum ieee80211_ampdu_mlme_action {
* @config_interface: Handler for configuration requests related to interfaces
* (e.g. BSSID changes.)
*
* @bss_info_changed: Handler for configuration requests related to BSS
* parameters that may vary during BSS's lifespan, and may affect low
* level driver (e.g. assoc/disassoc status, erp parameters).
* This function should not be used if no BSS has been set, unless
* for association indication. The @changed parameter indicates which
* of the bss parameters has changed when a call is made. This callback
* has to be atomic.
*
* @configure_filter: Configure the device's RX filter.
* See the section "Frame filtering" for more information.
* This callback must be implemented and atomic.
Expand Down Expand Up @@ -1038,8 +1070,6 @@ enum ieee80211_ampdu_mlme_action {
* @sta_notify: Notifies low level driver about addition or removal
* of assocaited station or AP.
*
* @erp_ie_changed: Handle ERP IE change notifications. Must be atomic.
*
* @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
* bursting) for a hardware TX queue. The @queue parameter uses the
* %IEEE80211_TX_QUEUE_* constants. Must be atomic.
Expand Down Expand Up @@ -1096,6 +1126,10 @@ struct ieee80211_ops {
int (*config_interface)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_if_conf *conf);
void (*bss_info_changed)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *info,
u32 changed);
void (*configure_filter)(struct ieee80211_hw *hw,
unsigned int changed_flags,
unsigned int *total_flags,
Expand All @@ -1115,8 +1149,6 @@ struct ieee80211_ops {
u32 short_retry, u32 long_retr);
void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
enum sta_notify_cmd, const u8 *addr);
void (*erp_ie_changed)(struct ieee80211_hw *hw, u8 changes,
int cts_protection, int preamble);
int (*conf_tx)(struct ieee80211_hw *hw, int queue,
const struct ieee80211_tx_queue_params *params);
int (*get_tx_stats)(struct ieee80211_hw *hw,
Expand Down
2 changes: 1 addition & 1 deletion net/mac80211/debugfs_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ static ssize_t ieee80211_if_fmt_flags(
sdata->u.sta.flags & IEEE80211_STA_AUTHENTICATED ? "AUTH\n" : "",
sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED ? "ASSOC\n" : "",
sdata->u.sta.flags & IEEE80211_STA_PROBEREQ_POLL ? "PROBEREQ POLL\n" : "",
sdata->flags & IEEE80211_SDATA_USE_PROTECTION ? "CTS prot\n" : "");
sdata->bss_conf.use_cts_prot ? "CTS prot\n" : "");
}
__IEEE80211_IF_FILE(flags);

Expand Down
29 changes: 17 additions & 12 deletions net/mac80211/ieee80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -635,25 +635,30 @@ int ieee80211_hw_config_ht(struct ieee80211_local *local, int enable_ht,
return 0;
}

void ieee80211_erp_info_change_notify(struct net_device *dev, u8 changes)
void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
u32 changed)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
if (local->ops->erp_ie_changed)
local->ops->erp_ie_changed(local_to_hw(local), changes,
!!(sdata->flags & IEEE80211_SDATA_USE_PROTECTION),
!(sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE));
struct ieee80211_local *local = sdata->local;

if (!changed)
return;

if (local->ops->bss_info_changed)
local->ops->bss_info_changed(local_to_hw(local),
&sdata->vif,
&sdata->bss_conf,
changed);
}

void ieee80211_reset_erp_info(struct net_device *dev)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);

sdata->flags &= ~(IEEE80211_SDATA_USE_PROTECTION |
IEEE80211_SDATA_SHORT_PREAMBLE);
ieee80211_erp_info_change_notify(dev,
IEEE80211_ERP_CHANGE_PROTECTION |
IEEE80211_ERP_CHANGE_PREAMBLE);
sdata->bss_conf.use_cts_prot = 0;
sdata->bss_conf.use_short_preamble = 0;
ieee80211_bss_info_change_notify(sdata,
BSS_CHANGED_ERP_CTS_PROT |
BSS_CHANGED_ERP_PREAMBLE);
}

void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
Expand Down
Loading

0 comments on commit 471b3ef

Please sign in to comment.