Commit b91a515d authored by Jussi Kivilinna's avatar Jussi Kivilinna Committed by John W. Linville

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: default avatarJussi Kivilinna <jussi.kivilinna@mbnet.fi>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent f773e409
...@@ -888,14 +888,36 @@ static int set_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s) ...@@ -888,14 +888,36 @@ static int set_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s)
} }
static int set_beacon_interval(struct zd_chip *chip, u32 interval) static int set_beacon_interval(struct zd_chip *chip, u16 interval,
u8 dtim_period, int type)
{ {
int r; int r;
struct aw_pt_bi s; struct aw_pt_bi s;
u32 b_interval, mode_flag;
ZD_ASSERT(mutex_is_locked(&chip->mutex)); ZD_ASSERT(mutex_is_locked(&chip->mutex));
r = zd_iowrite32_locked(chip, interval, CR_BCN_INTERVAL); if (interval > 0) {
switch (type) {
case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_MESH_POINT:
mode_flag = BCN_MODE_IBSS;
break;
case NL80211_IFTYPE_AP:
mode_flag = BCN_MODE_AP;
break;
default:
mode_flag = 0;
break;
}
} else {
dtim_period = 0;
mode_flag = 0;
}
b_interval = mode_flag | (dtim_period << 16) | interval;
r = zd_iowrite32_locked(chip, b_interval, CR_BCN_INTERVAL);
if (r) if (r)
return r; return r;
r = get_aw_pt_bi(chip, &s); r = get_aw_pt_bi(chip, &s);
...@@ -904,12 +926,13 @@ static int set_beacon_interval(struct zd_chip *chip, u32 interval) ...@@ -904,12 +926,13 @@ static int set_beacon_interval(struct zd_chip *chip, u32 interval)
return set_aw_pt_bi(chip, &s); return set_aw_pt_bi(chip, &s);
} }
int zd_set_beacon_interval(struct zd_chip *chip, u32 interval) int zd_set_beacon_interval(struct zd_chip *chip, u16 interval, u8 dtim_period,
int type)
{ {
int r; int r;
mutex_lock(&chip->mutex); mutex_lock(&chip->mutex);
r = set_beacon_interval(chip, interval); r = set_beacon_interval(chip, interval, dtim_period, type);
mutex_unlock(&chip->mutex); mutex_unlock(&chip->mutex);
return r; return r;
} }
...@@ -928,7 +951,7 @@ static int hw_init(struct zd_chip *chip) ...@@ -928,7 +951,7 @@ static int hw_init(struct zd_chip *chip)
if (r) if (r)
return r; return r;
return set_beacon_interval(chip, 100); return set_beacon_interval(chip, 100, 0, NL80211_IFTYPE_UNSPECIFIED);
} }
static zd_addr_t fw_reg_addr(struct zd_chip *chip, u16 offset) static zd_addr_t fw_reg_addr(struct zd_chip *chip, u16 offset)
......
...@@ -546,6 +546,7 @@ enum { ...@@ -546,6 +546,7 @@ enum {
#define RX_FILTER_CTRL (RX_FILTER_RTS | RX_FILTER_CTS | \ #define RX_FILTER_CTRL (RX_FILTER_RTS | RX_FILTER_CTS | \
RX_FILTER_CFEND | RX_FILTER_CFACK) RX_FILTER_CFEND | RX_FILTER_CFACK)
#define BCN_MODE_AP 0x1000000
#define BCN_MODE_IBSS 0x2000000 #define BCN_MODE_IBSS 0x2000000
/* Monitor mode sets filter to 0xfffff */ /* Monitor mode sets filter to 0xfffff */
...@@ -921,7 +922,8 @@ enum led_status { ...@@ -921,7 +922,8 @@ enum led_status {
int zd_chip_control_leds(struct zd_chip *chip, enum led_status status); int zd_chip_control_leds(struct zd_chip *chip, enum led_status status);
int zd_set_beacon_interval(struct zd_chip *chip, u32 interval); int zd_set_beacon_interval(struct zd_chip *chip, u16 interval, u8 dtim_period,
int type);
static inline int zd_get_beacon_interval(struct zd_chip *chip, u32 *interval) static inline int zd_get_beacon_interval(struct zd_chip *chip, u32 *interval)
{ {
......
...@@ -926,7 +926,7 @@ static void zd_op_remove_interface(struct ieee80211_hw *hw, ...@@ -926,7 +926,7 @@ static void zd_op_remove_interface(struct ieee80211_hw *hw,
struct zd_mac *mac = zd_hw_mac(hw); struct zd_mac *mac = zd_hw_mac(hw);
mac->type = NL80211_IFTYPE_UNSPECIFIED; mac->type = NL80211_IFTYPE_UNSPECIFIED;
mac->vif = NULL; mac->vif = NULL;
zd_set_beacon_interval(&mac->chip, 0); zd_set_beacon_interval(&mac->chip, 0, 0, NL80211_IFTYPE_UNSPECIFIED);
zd_write_mac_addr(&mac->chip, NULL); zd_write_mac_addr(&mac->chip, NULL);
} }
...@@ -1058,15 +1058,16 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw, ...@@ -1058,15 +1058,16 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
} }
if (changes & BSS_CHANGED_BEACON_ENABLED) { if (changes & BSS_CHANGED_BEACON_ENABLED) {
u32 interval; u16 interval = 0;
u8 period = 0;
if (bss_conf->enable_beacon) if (bss_conf->enable_beacon) {
interval = BCN_MODE_IBSS | period = bss_conf->dtim_period;
bss_conf->beacon_int; interval = bss_conf->beacon_int;
else }
interval = 0;
zd_set_beacon_interval(&mac->chip, interval); zd_set_beacon_interval(&mac->chip, interval, period,
mac->type);
} }
} else } else
associated = is_valid_ether_addr(bss_conf->bssid); associated = is_valid_ether_addr(bss_conf->bssid);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment