aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@mbnet.fi>2011-01-31 13:48:25 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-02-04 16:29:49 -0500
commitb91a515dbb4f824169755e071014230b57f0c1e1 (patch)
treeacfccf075ab0a98e8bd6dc02470b959aa4b2442f
parentf773e409b959677170b3cf1d573dafc4a0a3e34e (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.c33
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h4
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c17
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
891static int set_beacon_interval(struct zd_chip *chip, u32 interval) 891static 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
907int zd_set_beacon_interval(struct zd_chip *chip, u32 interval) 929int 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
934static zd_addr_t fw_reg_addr(struct zd_chip *chip, u16 offset) 957static 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
922int zd_chip_control_leds(struct zd_chip *chip, enum led_status status); 923int zd_chip_control_leds(struct zd_chip *chip, enum led_status status);
923 924
924int zd_set_beacon_interval(struct zd_chip *chip, u32 interval); 925int zd_set_beacon_interval(struct zd_chip *chip, u16 interval, u8 dtim_period,
926 int type);
925 927
926static inline int zd_get_beacon_interval(struct zd_chip *chip, u32 *interval) 928static 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);