diff options
author | Daniel Drake <dsd@gentoo.org> | 2007-07-27 09:43:24 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:47:39 -0400 |
commit | d9430a32886f70c0c16d67c525f6cda2df7906ee (patch) | |
tree | 9d531b23206e62033a6bb9d03ac572ce6ab4c7f1 | |
parent | 7e9ed18874f0df84b6651f0636e1cfdac43bc610 (diff) |
[MAC80211]: implement ERP info change notifications
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>
-rw-r--r-- | include/net/mac80211.h | 8 | ||||
-rw-r--r-- | net/mac80211/ieee80211.c | 25 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/ieee80211_ioctl.c | 16 | ||||
-rw-r--r-- | net/mac80211/ieee80211_sta.c | 10 |
5 files changed, 51 insertions, 10 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 3282038a1510..e503cd37f82e 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -697,6 +697,14 @@ struct ieee80211_ops { | |||
697 | void (*sta_table_notification)(struct ieee80211_hw *hw, | 697 | void (*sta_table_notification)(struct ieee80211_hw *hw, |
698 | int num_sta); | 698 | int num_sta); |
699 | 699 | ||
700 | /* Handle ERP IE change notifications. Must be atomic. */ | ||
701 | void (*erp_ie_changed)(struct ieee80211_hw *hw, u8 changes, | ||
702 | int cts_protection, int preamble); | ||
703 | |||
704 | /* Flags for the erp_ie_changed changes parameter */ | ||
705 | #define IEEE80211_ERP_CHANGE_PROTECTION (1<<0) /* protection flag changed */ | ||
706 | #define IEEE80211_ERP_CHANGE_PREAMBLE (1<<1) /* barker preamble mode changed */ | ||
707 | |||
700 | /* Configure TX queue parameters (EDCF (aifs, cw_min, cw_max), | 708 | /* Configure TX queue parameters (EDCF (aifs, cw_min, cw_max), |
701 | * bursting) for a hardware TX queue. | 709 | * bursting) for a hardware TX queue. |
702 | * queue = IEEE80211_TX_QUEUE_*. | 710 | * queue = IEEE80211_TX_QUEUE_*. |
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index f811a260ee9c..4715a9525918 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c | |||
@@ -464,8 +464,10 @@ static int ieee80211_open(struct net_device *dev) | |||
464 | if (sdata->type == IEEE80211_IF_TYPE_MNTR) { | 464 | if (sdata->type == IEEE80211_IF_TYPE_MNTR) { |
465 | local->monitors++; | 465 | local->monitors++; |
466 | local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP; | 466 | local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP; |
467 | } else | 467 | } else { |
468 | ieee80211_if_config(dev); | 468 | ieee80211_if_config(dev); |
469 | ieee80211_reset_erp_info(dev); | ||
470 | } | ||
469 | 471 | ||
470 | if (sdata->type == IEEE80211_IF_TYPE_STA && | 472 | if (sdata->type == IEEE80211_IF_TYPE_STA && |
471 | !local->user_space_mlme) | 473 | !local->user_space_mlme) |
@@ -748,6 +750,27 @@ int ieee80211_hw_config(struct ieee80211_local *local) | |||
748 | return ret; | 750 | return ret; |
749 | } | 751 | } |
750 | 752 | ||
753 | void ieee80211_erp_info_change_notify(struct net_device *dev, u8 changes) | ||
754 | { | ||
755 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
756 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
757 | if (local->ops->erp_ie_changed) | ||
758 | local->ops->erp_ie_changed(local_to_hw(local), changes, | ||
759 | sdata->use_protection, | ||
760 | !sdata->short_preamble); | ||
761 | } | ||
762 | |||
763 | void ieee80211_reset_erp_info(struct net_device *dev) | ||
764 | { | ||
765 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
766 | |||
767 | sdata->short_preamble = 0; | ||
768 | sdata->use_protection = 0; | ||
769 | ieee80211_erp_info_change_notify(dev, | ||
770 | IEEE80211_ERP_CHANGE_PROTECTION | | ||
771 | IEEE80211_ERP_CHANGE_PREAMBLE); | ||
772 | } | ||
773 | |||
751 | struct dev_mc_list *ieee80211_get_mc_list_item(struct ieee80211_hw *hw, | 774 | struct dev_mc_list *ieee80211_get_mc_list_item(struct ieee80211_hw *hw, |
752 | struct dev_mc_list *prev, | 775 | struct dev_mc_list *prev, |
753 | void **ptr) | 776 | void **ptr) |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index b0af6e9f5319..cc9999cd089c 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -788,6 +788,8 @@ struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, | |||
788 | u8 *addr); | 788 | u8 *addr); |
789 | int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason); | 789 | int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason); |
790 | int ieee80211_sta_disassociate(struct net_device *dev, u16 reason); | 790 | int ieee80211_sta_disassociate(struct net_device *dev, u16 reason); |
791 | void ieee80211_erp_info_change_notify(struct net_device *dev, u8 changes); | ||
792 | void ieee80211_reset_erp_info(struct net_device *dev); | ||
791 | 793 | ||
792 | /* ieee80211_iface.c */ | 794 | /* ieee80211_iface.c */ |
793 | int ieee80211_if_add(struct net_device *dev, const char *name, | 795 | int ieee80211_if_add(struct net_device *dev, const char *name, |
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c index 8292431ac48f..1fde214faecb 100644 --- a/net/mac80211/ieee80211_ioctl.c +++ b/net/mac80211/ieee80211_ioctl.c | |||
@@ -1054,17 +1054,21 @@ static int ieee80211_ioctl_prism2_param(struct net_device *dev, | |||
1054 | break; | 1054 | break; |
1055 | 1055 | ||
1056 | case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES: | 1056 | case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES: |
1057 | if (sdata->type != IEEE80211_IF_TYPE_AP) | 1057 | if (sdata->type == IEEE80211_IF_TYPE_AP) { |
1058 | sdata->use_protection = !!value; | ||
1059 | ieee80211_erp_info_change_notify(dev, IEEE80211_ERP_CHANGE_PROTECTION); | ||
1060 | } else { | ||
1058 | ret = -ENOENT; | 1061 | ret = -ENOENT; |
1059 | else | 1062 | } |
1060 | sdata->use_protection = value; | ||
1061 | break; | 1063 | break; |
1062 | 1064 | ||
1063 | case PRISM2_PARAM_PREAMBLE: | 1065 | case PRISM2_PARAM_PREAMBLE: |
1064 | if (sdata->type != IEEE80211_IF_TYPE_AP) | 1066 | if (sdata->type != IEEE80211_IF_TYPE_AP) { |
1067 | sdata->short_preamble = !!value; | ||
1068 | ieee80211_erp_info_change_notify(dev, IEEE80211_ERP_CHANGE_PREAMBLE); | ||
1069 | } else { | ||
1065 | ret = -ENOENT; | 1070 | ret = -ENOENT; |
1066 | else | 1071 | } |
1067 | sdata->short_preamble = value; | ||
1068 | break; | 1072 | break; |
1069 | 1073 | ||
1070 | case PRISM2_PARAM_STAT_TIME: | 1074 | case PRISM2_PARAM_STAT_TIME: |
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index 0f5f8131bd71..33414f160538 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c | |||
@@ -319,6 +319,7 @@ static void ieee80211_handle_erp_ie(struct net_device *dev, u8 erp_value) | |||
319 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 319 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; |
320 | int use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; | 320 | int use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; |
321 | int preamble_mode = (erp_value & WLAN_ERP_BARKER_PREAMBLE) != 0; | 321 | int preamble_mode = (erp_value & WLAN_ERP_BARKER_PREAMBLE) != 0; |
322 | u8 changes = 0; | ||
322 | 323 | ||
323 | if (use_protection != sdata->use_protection) { | 324 | if (use_protection != sdata->use_protection) { |
324 | if (net_ratelimit()) { | 325 | if (net_ratelimit()) { |
@@ -329,6 +330,7 @@ static void ieee80211_handle_erp_ie(struct net_device *dev, u8 erp_value) | |||
329 | MAC_ARG(ifsta->bssid)); | 330 | MAC_ARG(ifsta->bssid)); |
330 | } | 331 | } |
331 | sdata->use_protection = use_protection; | 332 | sdata->use_protection = use_protection; |
333 | changes |= IEEE80211_ERP_CHANGE_PROTECTION; | ||
332 | } | 334 | } |
333 | 335 | ||
334 | if (!preamble_mode != sdata->short_preamble) { | 336 | if (!preamble_mode != sdata->short_preamble) { |
@@ -341,7 +343,11 @@ static void ieee80211_handle_erp_ie(struct net_device *dev, u8 erp_value) | |||
341 | MAC_ARG(ifsta->bssid)); | 343 | MAC_ARG(ifsta->bssid)); |
342 | } | 344 | } |
343 | sdata->short_preamble = !preamble_mode; | 345 | sdata->short_preamble = !preamble_mode; |
346 | changes |= IEEE80211_ERP_CHANGE_PREAMBLE; | ||
344 | } | 347 | } |
348 | |||
349 | if (changes) | ||
350 | ieee80211_erp_info_change_notify(dev, changes); | ||
345 | } | 351 | } |
346 | 352 | ||
347 | 353 | ||
@@ -400,7 +406,6 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
400 | struct ieee80211_if_sta *ifsta, int assoc) | 406 | struct ieee80211_if_sta *ifsta, int assoc) |
401 | { | 407 | { |
402 | union iwreq_data wrqu; | 408 | union iwreq_data wrqu; |
403 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
404 | 409 | ||
405 | if (ifsta->associated == assoc) | 410 | if (ifsta->associated == assoc) |
406 | return; | 411 | return; |
@@ -428,8 +433,7 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
428 | ieee80211_sta_send_associnfo(dev, ifsta); | 433 | ieee80211_sta_send_associnfo(dev, ifsta); |
429 | } else { | 434 | } else { |
430 | netif_carrier_off(dev); | 435 | netif_carrier_off(dev); |
431 | sdata->short_preamble = 0; | 436 | ieee80211_reset_erp_info(dev); |
432 | sdata->use_protection = 0; | ||
433 | memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); | 437 | memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); |
434 | } | 438 | } |
435 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; | 439 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; |