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

Commit 294f32a7 authored by Gidon Studinski's avatar Gidon Studinski Committed by Maya Erez
Browse files

wil6210: initialize TX and RX enhanced DMA rings



Enhanced DMA design includes the following rings:
- Single RX descriptor ring is used for all VIFs
- Multiple RX status rings are supported, to allow RSS
- TX descriptor ring is allocated per connection
- A single TX status ring is used for all TX descriptor rings

This patch initializes and frees the above descriptor and
status rings.

The RX SKBs are handled by a new entity of RX buffers manager,
which handles RX buffers, each one points to an allocated SKB.
During Rx completion processing, the driver extracts a buffer
ID which is used as an index to the buffers array.
After the SKB is freed the buffer is moved from the 'active'
list to the 'free' list, indicating it can be used for another
descriptor. During Rx refill, SKBs are allocated and attached
to 'free' buffers. Those buffers are attached to new descriptors
and moved to the 'active' list.

Change-Id: Ia87d1c7197c97951e54f7be930ae808682e2644f
Signed-off-by: default avatarGidon Studinski <gidons@codeaurora.org>
Signed-off-by: default avatarMaya Erez <merez@codeaurora.org>
parent cfd6c54c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ wil6210-y += sysfs.o
wil6210-y += wmi.o
wil6210-y += interrupt.o
wil6210-y += txrx.o
wil6210-y += txrx_edma.o
wil6210-y += debug.o
wil6210-y += rx_reorder.o
wil6210-y += ioctl.o
+1 −0
Original line number Diff line number Diff line
@@ -1899,6 +1899,7 @@ static const struct dbg_off dbg_wil_off[] = {
	WIL_FIELD(abft_len, 0644,		doff_u8),
	WIL_FIELD(wakeup_trigger, 0644,		doff_u8),
	WIL_FIELD(ring_idle_trsh, 0644,	doff_u32),
	WIL_FIELD(num_rx_status_rings, 0644,	doff_u8),
	{},
};

+1 −1
Original line number Diff line number Diff line
@@ -101,7 +101,7 @@ static int wil_ethtoolops_set_coalesce(struct net_device *ndev,
	if (ret < 0)
		return ret;

	wil_configure_interrupt_moderation(wil);
	wil->txrx_ops.configure_interrupt_moderation(wil);

	wil_pm_runtime_put(wil);

+21 −0
Original line number Diff line number Diff line
@@ -186,6 +186,27 @@ void wil_unmask_irq(struct wil6210_priv *wil)
	wil6210_unmask_irq_misc(wil, true);
}

void wil_configure_interrupt_moderation_edma(struct wil6210_priv *wil)
{
	u32 moderation;

	wil_s(wil, RGF_INT_GEN_IDLE_TIME_LIMIT, WIL_EDMA_IDLE_TIME_LIMIT_USEC);

	wil_s(wil, RGF_INT_GEN_TIME_UNIT_LIMIT, WIL_EDMA_TIME_UNIT_CLK_CYCLES);

	/* Update RX and TX moderation */
	moderation = wil->rx_max_burst_duration |
		(WIL_EDMA_AGG_WATERMARK << WIL_EDMA_AGG_WATERMARK_POS);
	wil_w(wil, RGF_INT_CTRL_INT_GEN_CFG_0, moderation);
	wil_w(wil, RGF_INT_CTRL_INT_GEN_CFG_1, moderation);

	/* Treat special events as regular
	 * (set bit 0 to 0x1 and clear bits 1-8)
	 */
	wil_c(wil, RGF_INT_COUNT_ON_SPECIAL_EVT, 0x1FE);
	wil_s(wil, RGF_INT_COUNT_ON_SPECIAL_EVT, 0x1);
}

void wil_configure_interrupt_moderation(struct wil6210_priv *wil)
{
	struct wireless_dev *wdev = wil->main_ndev->ieee80211_ptr;
+63 −11
Original line number Diff line number Diff line
@@ -21,11 +21,13 @@

#include "wil6210.h"
#include "txrx.h"
#include "txrx_edma.h"
#include "wmi.h"
#include "boot_loader.h"

#define WAIT_FOR_HALP_VOTE_MS 100
#define WAIT_FOR_SCAN_ABORT_MS 1000
#define WIL_DEFAULT_NUM_RX_STATUS_RINGS 1

bool debug_fw; /* = false; */
module_param(debug_fw, bool, 0444);
@@ -160,6 +162,37 @@ void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
	}
}

static void wil_ring_fini_tx(struct wil6210_priv *wil, int id)
{
	struct wil_ring *ring = &wil->ring_tx[id];
	struct wil_ring_tx_data *txdata = &wil->ring_tx_data[id];

	lockdep_assert_held(&wil->mutex);

	if (!ring->va)
		return;

	wil_dbg_misc(wil, "vring_fini_tx: id=%d\n", id);

	spin_lock_bh(&txdata->lock);
	txdata->dot1x_open = false;
	txdata->mid = U8_MAX;
	txdata->enabled = 0; /* no Tx can be in progress or start anew */
	spin_unlock_bh(&txdata->lock);
	/* napi_synchronize waits for completion of the current NAPI but will
	 * not prevent the next NAPI run.
	 * Add a memory barrier to guarantee that txdata->enabled is zeroed
	 * before napi_synchronize so that the next scheduled NAPI will not
	 * handle this vring
	 */
	wmb();
	/* make sure NAPI won't touch this vring */
	if (test_bit(wil_status_napi_en, wil->status))
		napi_synchronize(&wil->napi_tx);

	wil->txrx_ops.ring_fini_tx(wil, ring);
}

static void wil_disconnect_cid(struct wil6210_vif *vif, int cid,
			       u16 reason_code, bool from_event)
__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
@@ -456,15 +489,16 @@ static void wil_fw_error_worker(struct work_struct *work)
static int wil_find_free_ring(struct wil6210_priv *wil)
{
	int i;
	int min_ring_id = wil_get_min_tx_ring_id(wil);

	for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
	for (i = min_ring_id; i < WIL6210_MAX_TX_RINGS; i++) {
		if (!wil->ring_tx[i].va)
			return i;
	}
	return -EINVAL;
}

int wil_tx_init(struct wil6210_vif *vif, int cid)
int wil_ring_init_tx(struct wil6210_vif *vif, int cid)
{
	struct wil6210_priv *wil = vif_to_wil(vif);
	int rc = -EINVAL, ringid;
@@ -482,7 +516,8 @@ int wil_tx_init(struct wil6210_vif *vif, int cid)
	wil_dbg_wmi(wil, "Configure for connection CID %d MID %d ring %d\n",
		    cid, vif->mid, ringid);

	rc = wil_vring_init_tx(vif, ringid, 1 << tx_ring_order, cid, 0);
	rc = wil->txrx_ops.ring_init_tx(vif, ringid, 1 << tx_ring_order,
					cid, 0);
	if (rc)
		wil_err(wil, "init TX for CID %d MID %d vring %d failed\n",
			cid, vif->mid, ringid);
@@ -504,7 +539,7 @@ int wil_bcast_init(struct wil6210_vif *vif)
		return ri;

	vif->bcast_ring = ri;
	rc = wil_vring_init_bcast(vif, ri, 1 << bcast_ring_order);
	rc = wil->txrx_ops.ring_init_bcast(vif, ri, 1 << bcast_ring_order);
	if (rc)
		vif->bcast_ring = -1;

@@ -594,6 +629,9 @@ int wil_priv_init(struct wil6210_priv *wil)
	wil->reply_mid = U8_MAX;
	wil->max_vifs = 1;

	/* num of rx srings can be updated via debugfs before allocation */
	wil->num_rx_status_rings = WIL_DEFAULT_NUM_RX_STATUS_RINGS;

	return 0;

out_wmi_wq:
@@ -1321,7 +1359,8 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
	rc = wil_target_reset(wil, no_flash);
	wil6210_clear_irq(wil);
	wil_enable_irq(wil);
	wil_rx_fini(wil);
	wil->txrx_ops.rx_fini(wil);
	wil->txrx_ops.tx_fini(wil);
	if (rc) {
		if (!no_flash)
			wil_bl_crash_info(wil, true);
@@ -1374,7 +1413,6 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
	clear_bit(wil_status_resetting, wil->status);

	if (load_fw) {
		wil_configure_interrupt_moderation(wil);
		wil_unmask_irq(wil);

		/* we just started MAC, wait for FW ready */
@@ -1389,6 +1427,8 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
			return rc;
		}

		wil->txrx_ops.configure_interrupt_moderation(wil);

		rc = wil_restore_vifs(wil);
		if (rc) {
			wil_err(wil, "failed to restore vifs, rc %d\n", rc);
@@ -1450,8 +1490,12 @@ int __wil_up(struct wil6210_priv *wil)
	if (rc)
		return rc;

	/* Rx VRING. After MAC and beacon */
	rc = wil_rx_init(wil, 1 << rx_ring_order);
	/* Rx RING. After MAC and beacon */
	rc = wil->txrx_ops.rx_init(wil, 1 << rx_ring_order);
	if (rc)
		return rc;

	rc = wil->txrx_ops.tx_init(wil);
	if (rc)
		return rc;

@@ -1613,3 +1657,11 @@ void wil_halp_unvote(struct wil6210_priv *wil)

	mutex_unlock(&wil->halp.lock);
}

void wil_init_txrx_ops(struct wil6210_priv *wil)
{
	if (wil->use_enhanced_dma_hw)
		wil_init_txrx_ops_edma(wil);
	else
		wil_init_txrx_ops_legacy_dma(wil);
}
Loading