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

Commit 86dff7a7 authored by Kalle Valo's avatar Kalle Valo Committed by John W. Linville
Browse files

wl1251: implement acx_ac_cfg to configure hardware queues



Needed for WMM.

Signed-off-by: default avatarKalle Valo <kalle.valo@nokia.com>
Reviewed-by: default avatarJanne Ylalehto <janne.ylalehto@nokia.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent cdd1e9a9
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -976,3 +976,36 @@ int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim)
	kfree(acx);
	return ret;
}

int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
		      u8 aifs, u16 txop)
{
	struct wl1251_acx_ac_cfg *acx;
	int ret = 0;

	wl1251_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
		     "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop);

	acx = kzalloc(sizeof(*acx), GFP_KERNEL);

	if (!acx) {
		ret = -ENOMEM;
		goto out;
	}

	acx->ac = ac;
	acx->cw_min = cw_min;
	acx->cw_max = cw_max;
	acx->aifsn = aifs;
	acx->txop_limit = txop;

	ret = wl1251_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
	if (ret < 0) {
		wl1251_warning("acx ac cfg failed: %d", ret);
		goto out;
	}

out:
	kfree(acx);
	return ret;
}
+32 −0
Original line number Diff line number Diff line
@@ -1166,6 +1166,36 @@ struct wl1251_acx_wr_tbtt_and_dtim {
	u8  padding;
} __attribute__ ((packed));

struct wl1251_acx_ac_cfg {
	struct acx_header header;

	/*
	 * Access Category - The TX queue's access category
	 * (refer to AccessCategory_enum)
	 */
	u8 ac;

	/*
	 * The contention window minimum size (in slots) for
	 * the access class.
	 */
	u8 cw_min;

	/*
	 * The contention window maximum size (in slots) for
	 * the access class.
	 */
	u16 cw_max;

	/* The AIF value (in slots) for the access class. */
	u8 aifsn;

	u8 reserved;

	/* The TX Op Limit (in microseconds) for the access class. */
	u16 txop_limit;
} __attribute__ ((packed));

/*************************************************************************

    Host Interrupt Register (WiLink -> Host)
@@ -1322,5 +1352,7 @@ int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime);
int wl1251_acx_rate_policies(struct wl1251 *wl);
int wl1251_acx_mem_cfg(struct wl1251 *wl);
int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim);
int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
		      u8 aifs, u16 txop);

#endif /* __WL1251_ACX_H__ */
+5 −0
Original line number Diff line number Diff line
@@ -294,6 +294,11 @@ static int wl1251_hw_init_tx_queue_config(struct wl1251 *wl)
			goto out;
	}

	wl1251_acx_ac_cfg(wl, AC_BE, CWMIN_BE, CWMAX_BE, AIFS_DIFS, TXOP_BE);
	wl1251_acx_ac_cfg(wl, AC_BK, CWMIN_BK, CWMAX_BK, AIFS_DIFS, TXOP_BK);
	wl1251_acx_ac_cfg(wl, AC_VI, CWMIN_VI, CWMAX_VI, AIFS_DIFS, TXOP_VI);
	wl1251_acx_ac_cfg(wl, AC_VO, CWMIN_VO, CWMAX_VO, AIFS_DIFS, TXOP_VO);

out:
	kfree(config);
	return ret;
+47 −0
Original line number Diff line number Diff line
@@ -26,6 +26,53 @@

#include "wl1251.h"

enum {
	/* best effort/legacy */
	AC_BE = 0,

	/* background */
	AC_BK = 1,

	/* video */
	AC_VI = 2,

	/* voice */
	AC_VO = 3,

	/* broadcast dummy access category */
	AC_BCAST = 4,

	NUM_ACCESS_CATEGORIES = 4
};

/* following are defult values for the IE fields*/
#define CWMIN_BK  15
#define CWMIN_BE  15
#define CWMIN_VI  7
#define CWMIN_VO  3
#define CWMAX_BK  1023
#define CWMAX_BE  63
#define CWMAX_VI  15
#define CWMAX_VO  7

/* slot number setting to start transmission at PIFS interval */
#define AIFS_PIFS 1

/*
 * slot number setting to start transmission at DIFS interval - normal DCF
 * access
 */
#define AIFS_DIFS 2

#define AIFSN_BK  7
#define AIFSN_BE  3
#define AIFSN_VI  AIFS_PIFS
#define AIFSN_VO  AIFS_PIFS
#define TXOP_BK   0
#define TXOP_BE   0
#define TXOP_VI   3008
#define TXOP_VO   1504

int wl1251_hw_init_hwenc_config(struct wl1251 *wl);
int wl1251_hw_init_templates_config(struct wl1251 *wl);
int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter);
+27 −0
Original line number Diff line number Diff line
@@ -1285,6 +1285,32 @@ static struct ieee80211_channel wl1251_channels[] = {
	{ .hw_value = 13, .center_freq = 2472},
};

static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
			     const struct ieee80211_tx_queue_params *params)
{
	struct wl1251 *wl = hw->priv;
	int ret;

	mutex_lock(&wl->mutex);

	wl1251_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue);

	ret = wl1251_ps_elp_wakeup(wl);
	if (ret < 0)
		goto out;

	ret = wl1251_acx_ac_cfg(wl, wl1251_tx_get_queue(queue),
				params->cw_min, params->cw_max,
				params->aifs, params->txop);

	wl1251_ps_elp_sleep(wl);

out:
	mutex_unlock(&wl->mutex);

	return ret;
}

/* can't be const, mac80211 writes to this */
static struct ieee80211_supported_band wl1251_band_2ghz = {
	.channels = wl1251_channels,
@@ -1305,6 +1331,7 @@ static const struct ieee80211_ops wl1251_ops = {
	.hw_scan = wl1251_op_hw_scan,
	.bss_info_changed = wl1251_op_bss_info_changed,
	.set_rts_threshold = wl1251_op_set_rts_threshold,
	.conf_tx = wl1251_op_conf_tx,
};

static int wl1251_register_hw(struct wl1251 *wl)
Loading