diff options
author | Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | 2011-01-31 13:48:25 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-02-04 16:29:49 -0500 |
commit | b91a515dbb4f824169755e071014230b57f0c1e1 (patch) | |
tree | acfccf075ab0a98e8bd6dc02470b959aa4b2442f | |
parent | f773e409b959677170b3cf1d573dafc4a0a3e34e (diff) |
zd1211rw: let zd_set_beacon_interval() set dtim_period and add AP-beacon flag
Add support for AP-mode beacon. Also disable beacon when interface is set
down as otherwise hw will keep flooding NEXT_BCN interrupts.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_chip.c | 33 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_chip.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 17 |
3 files changed, 40 insertions, 14 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 71d3cdebca14..d8dc92711f40 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c | |||
@@ -888,14 +888,36 @@ static int set_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s) | |||
888 | } | 888 | } |
889 | 889 | ||
890 | 890 | ||
891 | static int set_beacon_interval(struct zd_chip *chip, u32 interval) | 891 | static int set_beacon_interval(struct zd_chip *chip, u16 interval, |
892 | u8 dtim_period, int type) | ||
892 | { | 893 | { |
893 | int r; | 894 | int r; |
894 | struct aw_pt_bi s; | 895 | struct aw_pt_bi s; |
896 | u32 b_interval, mode_flag; | ||
895 | 897 | ||
896 | ZD_ASSERT(mutex_is_locked(&chip->mutex)); | 898 | ZD_ASSERT(mutex_is_locked(&chip->mutex)); |
897 | 899 | ||
898 | r = zd_iowrite32_locked(chip, interval, CR_BCN_INTERVAL); | 900 | if (interval > 0) { |
901 | switch (type) { | ||
902 | case NL80211_IFTYPE_ADHOC: | ||
903 | case NL80211_IFTYPE_MESH_POINT: | ||
904 | mode_flag = BCN_MODE_IBSS; | ||
905 | break; | ||
906 | case NL80211_IFTYPE_AP: | ||
907 | mode_flag = BCN_MODE_AP; | ||
908 | break; | ||
909 | default: | ||
910 | mode_flag = 0; | ||
911 | break; | ||
912 | } | ||
913 | } else { | ||
914 | dtim_period = 0; | ||
915 | mode_flag = 0; | ||
916 | } | ||
917 | |||
918 | b_interval = mode_flag | (dtim_period << 16) | interval; | ||
919 | |||
920 | r = zd_iowrite32_locked(chip, b_interval, CR_BCN_INTERVAL); | ||
899 | if (r) | 921 | if (r) |
900 | return r; | 922 | return r; |
901 | r = get_aw_pt_bi(chip, &s); | 923 | r = get_aw_pt_bi(chip, &s); |
@@ -904,12 +926,13 @@ static int set_beacon_interval(struct zd_chip *chip, u32 interval) | |||
904 | return set_aw_pt_bi(chip, &s); | 926 | return set_aw_pt_bi(chip, &s); |
905 | } | 927 | } |
906 | 928 | ||
907 | int zd_set_beacon_interval(struct zd_chip *chip, u32 interval) | 929 | int zd_set_beacon_interval(struct zd_chip *chip, u16 interval, u8 dtim_period, |
930 | int type) | ||
908 | { | 931 | { |
909 | int r; | 932 | int r; |
910 | 933 | ||
911 | mutex_lock(&chip->mutex); | 934 | mutex_lock(&chip->mutex); |
912 | r = set_beacon_interval(chip, interval); | 935 | r = set_beacon_interval(chip, interval, dtim_period, type); |
913 | mutex_unlock(&chip->mutex); | 936 | mutex_unlock(&chip->mutex); |
914 | return r; | 937 | return r; |
915 | } | 938 | } |
@@ -928,7 +951,7 @@ static int hw_init(struct zd_chip *chip) | |||
928 | if (r) | 951 | if (r) |
929 | return r; | 952 | return r; |
930 | 953 | ||
931 | return set_beacon_interval(chip, 100); | 954 | return set_beacon_interval(chip, 100, 0, NL80211_IFTYPE_UNSPECIFIED); |
932 | } | 955 | } |
933 | 956 | ||
934 | static zd_addr_t fw_reg_addr(struct zd_chip *chip, u16 offset) | 957 | static zd_addr_t fw_reg_addr(struct zd_chip *chip, u16 offset) |
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index 7b0c58ce7056..14e4402a6111 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h | |||
@@ -546,6 +546,7 @@ enum { | |||
546 | #define RX_FILTER_CTRL (RX_FILTER_RTS | RX_FILTER_CTS | \ | 546 | #define RX_FILTER_CTRL (RX_FILTER_RTS | RX_FILTER_CTS | \ |
547 | RX_FILTER_CFEND | RX_FILTER_CFACK) | 547 | RX_FILTER_CFEND | RX_FILTER_CFACK) |
548 | 548 | ||
549 | #define BCN_MODE_AP 0x1000000 | ||
549 | #define BCN_MODE_IBSS 0x2000000 | 550 | #define BCN_MODE_IBSS 0x2000000 |
550 | 551 | ||
551 | /* Monitor mode sets filter to 0xfffff */ | 552 | /* Monitor mode sets filter to 0xfffff */ |
@@ -921,7 +922,8 @@ enum led_status { | |||
921 | 922 | ||
922 | int zd_chip_control_leds(struct zd_chip *chip, enum led_status status); | 923 | int zd_chip_control_leds(struct zd_chip *chip, enum led_status status); |
923 | 924 | ||
924 | int zd_set_beacon_interval(struct zd_chip *chip, u32 interval); | 925 | int zd_set_beacon_interval(struct zd_chip *chip, u16 interval, u8 dtim_period, |
926 | int type); | ||
925 | 927 | ||
926 | static inline int zd_get_beacon_interval(struct zd_chip *chip, u32 *interval) | 928 | static inline int zd_get_beacon_interval(struct zd_chip *chip, u32 *interval) |
927 | { | 929 | { |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 84ac95eb59fa..1bd275bc6084 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -926,7 +926,7 @@ static void zd_op_remove_interface(struct ieee80211_hw *hw, | |||
926 | struct zd_mac *mac = zd_hw_mac(hw); | 926 | struct zd_mac *mac = zd_hw_mac(hw); |
927 | mac->type = NL80211_IFTYPE_UNSPECIFIED; | 927 | mac->type = NL80211_IFTYPE_UNSPECIFIED; |
928 | mac->vif = NULL; | 928 | mac->vif = NULL; |
929 | zd_set_beacon_interval(&mac->chip, 0); | 929 | zd_set_beacon_interval(&mac->chip, 0, 0, NL80211_IFTYPE_UNSPECIFIED); |
930 | zd_write_mac_addr(&mac->chip, NULL); | 930 | zd_write_mac_addr(&mac->chip, NULL); |
931 | } | 931 | } |
932 | 932 | ||
@@ -1058,15 +1058,16 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1058 | } | 1058 | } |
1059 | 1059 | ||
1060 | if (changes & BSS_CHANGED_BEACON_ENABLED) { | 1060 | if (changes & BSS_CHANGED_BEACON_ENABLED) { |
1061 | u32 interval; | 1061 | u16 interval = 0; |
1062 | u8 period = 0; | ||
1062 | 1063 | ||
1063 | if (bss_conf->enable_beacon) | 1064 | if (bss_conf->enable_beacon) { |
1064 | interval = BCN_MODE_IBSS | | 1065 | period = bss_conf->dtim_period; |
1065 | bss_conf->beacon_int; | 1066 | interval = bss_conf->beacon_int; |
1066 | else | 1067 | } |
1067 | interval = 0; | ||
1068 | 1068 | ||
1069 | zd_set_beacon_interval(&mac->chip, interval); | 1069 | zd_set_beacon_interval(&mac->chip, interval, period, |
1070 | mac->type); | ||
1070 | } | 1071 | } |
1071 | } else | 1072 | } else |
1072 | associated = is_valid_ether_addr(bss_conf->bssid); | 1073 | associated = is_valid_ether_addr(bss_conf->bssid); |