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>
This commit is contained in:
Jussi Kivilinna 2011-01-31 20:48:25 +02:00 committed by John W. Linville
parent f773e409b9
commit b91a515dbb
3 changed files with 40 additions and 14 deletions

View File

@ -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;
struct aw_pt_bi s;
u32 b_interval, mode_flag;
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)
return r;
r = get_aw_pt_bi(chip, &s);
@ -904,12 +926,13 @@ static int set_beacon_interval(struct zd_chip *chip, u32 interval)
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;
mutex_lock(&chip->mutex);
r = set_beacon_interval(chip, interval);
r = set_beacon_interval(chip, interval, dtim_period, type);
mutex_unlock(&chip->mutex);
return r;
}
@ -928,7 +951,7 @@ static int hw_init(struct zd_chip *chip)
if (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)

View File

@ -546,6 +546,7 @@ enum {
#define RX_FILTER_CTRL (RX_FILTER_RTS | RX_FILTER_CTS | \
RX_FILTER_CFEND | RX_FILTER_CFACK)
#define BCN_MODE_AP 0x1000000
#define BCN_MODE_IBSS 0x2000000
/* Monitor mode sets filter to 0xfffff */
@ -921,7 +922,8 @@ enum led_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)
{

View File

@ -926,7 +926,7 @@ static void zd_op_remove_interface(struct ieee80211_hw *hw,
struct zd_mac *mac = zd_hw_mac(hw);
mac->type = NL80211_IFTYPE_UNSPECIFIED;
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);
}
@ -1058,15 +1058,16 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
}
if (changes & BSS_CHANGED_BEACON_ENABLED) {
u32 interval;
u16 interval = 0;
u8 period = 0;
if (bss_conf->enable_beacon)
interval = BCN_MODE_IBSS |
bss_conf->beacon_int;
else
interval = 0;
if (bss_conf->enable_beacon) {
period = bss_conf->dtim_period;
interval = bss_conf->beacon_int;
}
zd_set_beacon_interval(&mac->chip, interval);
zd_set_beacon_interval(&mac->chip, interval, period,
mac->type);
}
} else
associated = is_valid_ether_addr(bss_conf->bssid);