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

Commit a1c597f2 authored by Arik Nemtsov's avatar Arik Nemtsov Committed by Luciano Coelho
Browse files

wlcore/wl12xx/wl18xx: implement op_set_key per HW arch



The 12xx set_key just calls the common wlcore_set_key function, in order
to program the keys into the FW.

The 18xx variant changes the spare block count when a GEM or TKIP
key is set. Also modify the get_spare_blocks HW op for 18xx to return
the correct numbers of spare blocks, according to what is currently
set in FW.

Signed-off-by: default avatarArik Nemtsov <arik@wizery.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent 2c38849f
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1369,6 +1369,14 @@ static int wl12xx_get_spare_blocks(struct wl1271 *wl, bool is_gem)
	return WL12XX_TX_HW_BLOCK_SPARE_DEFAULT;
}

static int wl12xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
			  struct ieee80211_vif *vif,
			  struct ieee80211_sta *sta,
			  struct ieee80211_key_conf *key_conf)
{
	return wlcore_set_key(wl, cmd, vif, sta, key_conf);
}

static struct wlcore_ops wl12xx_ops = {
	.identify_chip		= wl12xx_identify_chip,
	.identify_fw		= wl12xx_identify_fw,
@@ -1393,6 +1401,7 @@ static struct wlcore_ops wl12xx_ops = {
	.ap_get_mimo_wide_rate_mask = NULL,
	.debugfs_init		= wl12xx_debugfs_add_files,
	.get_spare_blocks	= wl12xx_get_spare_blocks,
	.set_key		= wl12xx_set_key,
};

static struct ieee80211_sta_ht_cap wl12xx_ht_cap = {
+4 −0
Original line number Diff line number Diff line
@@ -32,6 +32,10 @@ int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap,
	struct wl18xx_acx_host_config_bitmap *bitmap_conf;
	int ret;

	wl1271_debug(DEBUG_ACX, "acx cfg bitmap %d blk %d spare %d field %d",
		     host_cfg_bitmap, sdio_blk_size, extra_mem_blks,
		     len_field_size);

	bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL);
	if (!bitmap_conf) {
		ret = -ENOMEM;
+84 −12
Original line number Diff line number Diff line
@@ -848,18 +848,13 @@ static void wl18xx_tx_immediate_completion(struct wl1271 *wl)
	wl18xx_tx_immediate_complete(wl);
}

static int wl18xx_hw_init(struct wl1271 *wl)
static int wl18xx_set_host_cfg_bitmap(struct wl1271 *wl, u32 extra_mem_blk)
{
	int ret;
	struct wl18xx_priv *priv = wl->priv;
	u32 sdio_align_size = 0;
	u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE |
			      HOST_IF_CFG_ADD_RX_ALIGNMENT;

	u32 sdio_align_size = 0;

	/* (re)init private structures. Relevant on recovery as well. */
	priv->last_fw_rls_idx = 0;

	/* Enable Tx SDIO padding */
	if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN) {
		host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
@@ -873,12 +868,28 @@ static int wl18xx_hw_init(struct wl1271 *wl)
	}

	ret = wl18xx_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap,
					    sdio_align_size,
					    WL18XX_TX_HW_EXTRA_BLOCK_SPARE,
					    sdio_align_size, extra_mem_blk,
					    WL18XX_HOST_IF_LEN_SIZE_FIELD);
	if (ret < 0)
		return ret;

	return 0;
}

static int wl18xx_hw_init(struct wl1271 *wl)
{
	int ret;
	struct wl18xx_priv *priv = wl->priv;

	/* (re)init private structures. Relevant on recovery as well. */
	priv->last_fw_rls_idx = 0;
	priv->extra_spare_vif_count = 0;

	/* set the default amount of spare blocks in the bitmap */
	ret = wl18xx_set_host_cfg_bitmap(wl, WL18XX_TX_HW_BLOCK_SPARE);
	if (ret < 0)
		return ret;

	if (checksum_param) {
		ret = wl18xx_acx_set_checksum_state(wl);
		if (ret != 0)
@@ -1036,8 +1047,68 @@ static int wl18xx_handle_static_data(struct wl1271 *wl,

static int wl18xx_get_spare_blocks(struct wl1271 *wl, bool is_gem)
{
	/* TODO: dynamically change to extra only when we have GEM or TKIP */
	struct wl18xx_priv *priv = wl->priv;

	/* If we have VIFs requiring extra spare, indulge them */
	if (priv->extra_spare_vif_count)
		return WL18XX_TX_HW_EXTRA_BLOCK_SPARE;

	return WL18XX_TX_HW_BLOCK_SPARE;
}

static int wl18xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
			  struct ieee80211_vif *vif,
			  struct ieee80211_sta *sta,
			  struct ieee80211_key_conf *key_conf)
{
	struct wl18xx_priv *priv = wl->priv;
	bool change_spare = false;
	int ret;

	/*
	 * when adding the first or removing the last GEM/TKIP interface,
	 * we have to adjust the number of spare blocks.
	 */
	change_spare = (key_conf->cipher == WL1271_CIPHER_SUITE_GEM ||
		key_conf->cipher == WLAN_CIPHER_SUITE_TKIP) &&
		((priv->extra_spare_vif_count == 0 && cmd == SET_KEY) ||
		 (priv->extra_spare_vif_count == 1 && cmd == DISABLE_KEY));

	/* no need to change spare - just regular set_key */
	if (!change_spare)
		return wlcore_set_key(wl, cmd, vif, sta, key_conf);

	/*
	 * stop the queues and flush to ensure the next packets are
	 * in sync with FW spare block accounting
	 */
	wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK);
	wl1271_tx_flush(wl);

	ret = wlcore_set_key(wl, cmd, vif, sta, key_conf);
	if (ret < 0)
		goto out;

	/* key is now set, change the spare blocks */
	if (cmd == SET_KEY) {
		ret = wl18xx_set_host_cfg_bitmap(wl,
					WL18XX_TX_HW_EXTRA_BLOCK_SPARE);
		if (ret < 0)
			goto out;

		priv->extra_spare_vif_count++;
	} else {
		ret = wl18xx_set_host_cfg_bitmap(wl,
					WL18XX_TX_HW_BLOCK_SPARE);
		if (ret < 0)
			goto out;

		priv->extra_spare_vif_count--;
	}

out:
	wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK);
	return ret;
}

static struct wlcore_ops wl18xx_ops = {
@@ -1063,6 +1134,7 @@ static struct wlcore_ops wl18xx_ops = {
	.debugfs_init	= wl18xx_debugfs_add_files,
	.handle_static_data	= wl18xx_handle_static_data,
	.get_spare_blocks = wl18xx_get_spare_blocks,
	.set_key	= wl18xx_set_key,
};

/* HT cap appropriate for wide channels */
+3 −0
Original line number Diff line number Diff line
@@ -36,6 +36,9 @@ struct wl18xx_priv {
	u8 last_fw_rls_idx;

	u8 board_type;

	/* number of VIFs requiring extra spare mem-blocks */
	int extra_spare_vif_count;
};

#define WL18XX_FW_MAX_TX_STATUS_DESC 33
+12 −0
Original line number Diff line number Diff line
@@ -176,4 +176,16 @@ wlcore_hw_get_spare_blocks(struct wl1271 *wl, bool is_gem)
	return wl->ops->get_spare_blocks(wl, is_gem);
}

static inline int
wlcore_hw_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
		  struct ieee80211_vif *vif,
		  struct ieee80211_sta *sta,
		  struct ieee80211_key_conf *key_conf)
{
	if (!wl->ops->set_key)
		BUG_ON(1);

	return wl->ops->set_key(wl, cmd, vif, sta, key_conf);
}

#endif
Loading