Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+28 −5
Original line number Original line Diff line number Diff line
@@ -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)
+3 −1
Original line number Original line Diff line number Diff line
@@ -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)
{
{
+9 −8
Original line number Original line Diff line number Diff line
@@ -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);