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:
parent
f773e409b9
commit
b91a515dbb
|
@ -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)
|
||||||
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)
|
||||||
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 {
|
||||||
#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 {
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue