Skip to content

Commit

Permalink
[MAC80211]: implement ERP info change notifications
Browse files Browse the repository at this point in the history
zd1211rw and bcm43xx are interested in being notified when ERP IE conditions
change, so that they can reprogram a register which affects how control frames
are transmitted.

This patch adds an interface similar to the one that can be found in softmac.

Signed-off-by: Daniel Drake <dsd@gentoo.org>
Signed-off-by: Jiri Benc <jbenc@suse.cz>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Daniel Drake authored and David S. Miller committed Oct 10, 2007
1 parent 7e9ed18 commit d9430a3
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 10 deletions.
8 changes: 8 additions & 0 deletions include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,14 @@ struct ieee80211_ops {
void (*sta_table_notification)(struct ieee80211_hw *hw,
int num_sta);

/* Handle ERP IE change notifications. Must be atomic. */
void (*erp_ie_changed)(struct ieee80211_hw *hw, u8 changes,
int cts_protection, int preamble);

/* Flags for the erp_ie_changed changes parameter */
#define IEEE80211_ERP_CHANGE_PROTECTION (1<<0) /* protection flag changed */
#define IEEE80211_ERP_CHANGE_PREAMBLE (1<<1) /* barker preamble mode changed */

/* Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
* bursting) for a hardware TX queue.
* queue = IEEE80211_TX_QUEUE_*.
Expand Down
25 changes: 24 additions & 1 deletion net/mac80211/ieee80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -464,8 +464,10 @@ static int ieee80211_open(struct net_device *dev)
if (sdata->type == IEEE80211_IF_TYPE_MNTR) {
local->monitors++;
local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP;
} else
} else {
ieee80211_if_config(dev);
ieee80211_reset_erp_info(dev);
}

if (sdata->type == IEEE80211_IF_TYPE_STA &&
!local->user_space_mlme)
Expand Down Expand Up @@ -748,6 +750,27 @@ int ieee80211_hw_config(struct ieee80211_local *local)
return ret;
}

void ieee80211_erp_info_change_notify(struct net_device *dev, u8 changes)
{
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->use_protection,
!sdata->short_preamble);
}

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

sdata->short_preamble = 0;
sdata->use_protection = 0;
ieee80211_erp_info_change_notify(dev,
IEEE80211_ERP_CHANGE_PROTECTION |
IEEE80211_ERP_CHANGE_PREAMBLE);
}

struct dev_mc_list *ieee80211_get_mc_list_item(struct ieee80211_hw *hw,
struct dev_mc_list *prev,
void **ptr)
Expand Down
2 changes: 2 additions & 0 deletions net/mac80211/ieee80211_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,8 @@ struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev,
u8 *addr);
int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason);
int ieee80211_sta_disassociate(struct net_device *dev, u16 reason);
void ieee80211_erp_info_change_notify(struct net_device *dev, u8 changes);
void ieee80211_reset_erp_info(struct net_device *dev);

/* ieee80211_iface.c */
int ieee80211_if_add(struct net_device *dev, const char *name,
Expand Down
16 changes: 10 additions & 6 deletions net/mac80211/ieee80211_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1054,17 +1054,21 @@ static int ieee80211_ioctl_prism2_param(struct net_device *dev,
break;

case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES:
if (sdata->type != IEEE80211_IF_TYPE_AP)
if (sdata->type == IEEE80211_IF_TYPE_AP) {
sdata->use_protection = !!value;
ieee80211_erp_info_change_notify(dev, IEEE80211_ERP_CHANGE_PROTECTION);
} else {
ret = -ENOENT;
else
sdata->use_protection = value;
}
break;

case PRISM2_PARAM_PREAMBLE:
if (sdata->type != IEEE80211_IF_TYPE_AP)
if (sdata->type != IEEE80211_IF_TYPE_AP) {
sdata->short_preamble = !!value;
ieee80211_erp_info_change_notify(dev, IEEE80211_ERP_CHANGE_PREAMBLE);
} else {
ret = -ENOENT;
else
sdata->short_preamble = value;
}
break;

case PRISM2_PARAM_STAT_TIME:
Expand Down
10 changes: 7 additions & 3 deletions net/mac80211/ieee80211_sta.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ static void ieee80211_handle_erp_ie(struct net_device *dev, u8 erp_value)
struct ieee80211_if_sta *ifsta = &sdata->u.sta;
int use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
int preamble_mode = (erp_value & WLAN_ERP_BARKER_PREAMBLE) != 0;
u8 changes = 0;

if (use_protection != sdata->use_protection) {
if (net_ratelimit()) {
Expand All @@ -329,6 +330,7 @@ static void ieee80211_handle_erp_ie(struct net_device *dev, u8 erp_value)
MAC_ARG(ifsta->bssid));
}
sdata->use_protection = use_protection;
changes |= IEEE80211_ERP_CHANGE_PROTECTION;
}

if (!preamble_mode != sdata->short_preamble) {
Expand All @@ -341,7 +343,11 @@ static void ieee80211_handle_erp_ie(struct net_device *dev, u8 erp_value)
MAC_ARG(ifsta->bssid));
}
sdata->short_preamble = !preamble_mode;
changes |= IEEE80211_ERP_CHANGE_PREAMBLE;
}

if (changes)
ieee80211_erp_info_change_notify(dev, changes);
}


Expand Down Expand Up @@ -400,7 +406,6 @@ static void ieee80211_set_associated(struct net_device *dev,
struct ieee80211_if_sta *ifsta, int assoc)
{
union iwreq_data wrqu;
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);

if (ifsta->associated == assoc)
return;
Expand Down Expand Up @@ -428,8 +433,7 @@ static void ieee80211_set_associated(struct net_device *dev,
ieee80211_sta_send_associnfo(dev, ifsta);
} else {
netif_carrier_off(dev);
sdata->short_preamble = 0;
sdata->use_protection = 0;
ieee80211_reset_erp_info(dev);
memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
}
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
Expand Down

0 comments on commit d9430a3

Please sign in to comment.