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

Commit e0d0b5c1 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "wil6210: add support for enhanced DMA structures" into msm-4.14

parents f3d38f74 cfd6c54c
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -1827,7 +1827,7 @@ static int wil_cfg80211_change_station(struct wiphy *wiphy,
	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
	int authorize;
	int cid, i;
	struct vring_tx_data *txdata = NULL;
	struct wil_ring_tx_data *txdata = NULL;

	wil_dbg_misc(wil, "change station %pM mask 0x%x set 0x%x mid %d\n",
		     mac, params->sta_flags_mask, params->sta_flags_set,
@@ -1847,20 +1847,20 @@ static int wil_cfg80211_change_station(struct wiphy *wiphy,
		return -ENOLINK;
	}

	for (i = 0; i < ARRAY_SIZE(wil->vring2cid_tid); i++)
		if (wil->vring2cid_tid[i][0] == cid) {
			txdata = &wil->vring_tx_data[i];
	for (i = 0; i < ARRAY_SIZE(wil->ring2cid_tid); i++)
		if (wil->ring2cid_tid[i][0] == cid) {
			txdata = &wil->ring_tx_data[i];
			break;
		}

	if (!txdata) {
		wil_err(wil, "vring data not found\n");
		wil_err(wil, "ring data not found\n");
		return -ENOLINK;
	}

	authorize = params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED);
	txdata->dot1x_open = authorize ? 1 : 0;
	wil_dbg_misc(wil, "cid %d vring %d authorize %d\n", cid, i,
	wil_dbg_misc(wil, "cid %d ring %d authorize %d\n", cid, i,
		     txdata->dot1x_open);

	return 0;
+56 −55
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@
/* Nasty hack. Better have per device instances */
static u32 mem_addr;
static u32 dbg_txdesc_index;
static u32 dbg_vring_index; /* 24+ for Rx, 0..23 for Tx */
static u32 dbg_ring_index; /* 24+ for Rx, 0..23 for Tx */

enum dbg_off_type {
	doff_u32 = 0,
@@ -47,20 +47,20 @@ struct dbg_off {
	enum dbg_off_type type;
};

static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil,
			    const char *name, struct vring *vring,
static void wil_print_ring(struct seq_file *s, struct wil6210_priv *wil,
			   const char *name, struct wil_ring *ring,
			   char _s, char _h)
{
	void __iomem *x = wmi_addr(wil, vring->hwtail);
	void __iomem *x = wmi_addr(wil, ring->hwtail);
	u32 v;

	seq_printf(s, "VRING %s = {\n", name);
	seq_printf(s, "  pa     = %pad\n", &vring->pa);
	seq_printf(s, "  va     = 0x%p\n", vring->va);
	seq_printf(s, "  size   = %d\n", vring->size);
	seq_printf(s, "  swtail = %d\n", vring->swtail);
	seq_printf(s, "  swhead = %d\n", vring->swhead);
	seq_printf(s, "  hwtail = [0x%08x] -> ", vring->hwtail);
	seq_printf(s, "RING %s = {\n", name);
	seq_printf(s, "  pa     = %pad\n", &ring->pa);
	seq_printf(s, "  va     = 0x%p\n", ring->va);
	seq_printf(s, "  size   = %d\n", ring->size);
	seq_printf(s, "  swtail = %d\n", ring->swtail);
	seq_printf(s, "  swhead = %d\n", ring->swhead);
	seq_printf(s, "  hwtail = [0x%08x] -> ", ring->hwtail);
	if (x) {
		v = readl(x);
		seq_printf(s, "0x%08x = %d\n", v, v);
@@ -68,41 +68,42 @@ static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil,
		seq_puts(s, "???\n");
	}

	if (vring->va && (vring->size <= (1 << WIL_RING_SIZE_ORDER_MAX))) {
	if (ring->va && (ring->size <= (1 << WIL_RING_SIZE_ORDER_MAX))) {
		uint i;

		for (i = 0; i < vring->size; i++) {
			volatile struct vring_tx_desc *d = &vring->va[i].tx;
		for (i = 0; i < ring->size; i++) {
			volatile struct vring_tx_desc *d =
				&ring->va[i].tx.legacy;

			if ((i % 128) == 0 && (i != 0))
				seq_puts(s, "\n");
			seq_printf(s, "%c", (d->dma.status & BIT(0)) ?
					_s : (vring->ctx[i].skb ? _h : 'h'));
					_s : (ring->ctx[i].skb ? _h : 'h'));
		}
		seq_puts(s, "\n");
	}
	seq_puts(s, "}\n");
}

static int wil_vring_debugfs_show(struct seq_file *s, void *data)
static int wil_ring_debugfs_show(struct seq_file *s, void *data)
{
	uint i;
	struct wil6210_priv *wil = s->private;

	wil_print_vring(s, wil, "rx", &wil->vring_rx, 'S', '_');
	wil_print_ring(s, wil, "rx", &wil->ring_rx, 'S', '_');

	for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) {
		struct vring *vring = &wil->vring_tx[i];
		struct vring_tx_data *txdata = &wil->vring_tx_data[i];
	for (i = 0; i < ARRAY_SIZE(wil->ring_tx); i++) {
		struct wil_ring *ring = &wil->ring_tx[i];
		struct wil_ring_tx_data *txdata = &wil->ring_tx_data[i];

		if (vring->va) {
			int cid = wil->vring2cid_tid[i][0];
			int tid = wil->vring2cid_tid[i][1];
			u32 swhead = vring->swhead;
			u32 swtail = vring->swtail;
			int used = (vring->size + swhead - swtail)
				   % vring->size;
			int avail = vring->size - used - 1;
		if (ring->va) {
			int cid = wil->ring2cid_tid[i][0];
			int tid = wil->ring2cid_tid[i][1];
			u32 swhead = ring->swhead;
			u32 swtail = ring->swtail;
			int used = (ring->size + swhead - swtail)
				   % ring->size;
			int avail = ring->size - used - 1;
			char name[10];
			char sidle[10];
			/* performance monitoring */
@@ -137,20 +138,20 @@ static int wil_vring_debugfs_show(struct seq_file *s, void *data)
					   txdata->dot1x_open ? "+" : "-",
					   used, avail, sidle);

			wil_print_vring(s, wil, name, vring, '_', 'H');
			wil_print_ring(s, wil, name, ring, '_', 'H');
		}
	}

	return 0;
}

static int wil_vring_seq_open(struct inode *inode, struct file *file)
static int wil_ring_seq_open(struct inode *inode, struct file *file)
{
	return single_open(file, wil_vring_debugfs_show, inode->i_private);
	return single_open(file, wil_ring_debugfs_show, inode->i_private);
}

static const struct file_operations fops_vring = {
	.open		= wil_vring_seq_open,
static const struct file_operations fops_ring = {
	.open		= wil_ring_seq_open,
	.release	= single_release,
	.read		= seq_read,
	.llseek		= seq_lseek,
@@ -162,7 +163,7 @@ static void wil_seq_hexdump(struct seq_file *s, void *p, int len,
	seq_hex_dump(s, prefix, DUMP_PREFIX_NONE, 16, 1, p, len, false);
}

static void wil_print_ring(struct seq_file *s, const char *prefix,
static void wil_print_mbox_ring(struct seq_file *s, const char *prefix,
				void __iomem *off)
{
	struct wil6210_priv *wil = s->private;
@@ -249,9 +250,9 @@ static int wil_mbox_debugfs_show(struct seq_file *s, void *data)
	if (ret < 0)
		return ret;

	wil_print_ring(s, "tx", wil->csr + HOST_MBOX +
	wil_print_mbox_ring(s, "tx", wil->csr + HOST_MBOX +
		       offsetof(struct wil6210_mbox_ctl, tx));
	wil_print_ring(s, "rx", wil->csr + HOST_MBOX +
	wil_print_mbox_ring(s, "rx", wil->csr + HOST_MBOX +
		       offsetof(struct wil6210_mbox_ctl, rx));

	wil_pm_runtime_put(wil);
@@ -720,13 +721,13 @@ static ssize_t wil_write_back(struct file *file, const char __user *buf,

	if ((strcmp(cmd, "add") == 0) ||
	    (strcmp(cmd, "del_tx") == 0)) {
		struct vring_tx_data *txdata;
		struct wil_ring_tx_data *txdata;

		if (p1 < 0 || p1 >= WIL6210_MAX_TX_RINGS) {
			wil_err(wil, "BACK: invalid ring id %d\n", p1);
			return -EINVAL;
		}
		txdata = &wil->vring_tx_data[p1];
		txdata = &wil->ring_tx_data[p1];
		if (strcmp(cmd, "add") == 0) {
			if (rc < 3) {
				wil_err(wil, "BACK: add require at least 2 params\n");
@@ -973,30 +974,30 @@ static void wil_seq_print_skb(struct seq_file *s, struct sk_buff *skb)
static int wil_txdesc_debugfs_show(struct seq_file *s, void *data)
{
	struct wil6210_priv *wil = s->private;
	struct vring *vring;
	bool tx = (dbg_vring_index < WIL6210_MAX_TX_RINGS);
	struct wil_ring *ring;
	bool tx = (dbg_ring_index < WIL6210_MAX_TX_RINGS);

	vring = tx ? &wil->vring_tx[dbg_vring_index] : &wil->vring_rx;
	ring = tx ? &wil->ring_tx[dbg_ring_index] : &wil->ring_rx;

	if (!vring->va) {
	if (!ring->va) {
		if (tx)
			seq_printf(s, "No Tx[%2d] VRING\n", dbg_vring_index);
			seq_printf(s, "No Tx[%2d] VRING\n", dbg_ring_index);
		else
			seq_puts(s, "No Rx VRING\n");
		return 0;
	}

	if (dbg_txdesc_index < vring->size) {
	if (dbg_txdesc_index < ring->size) {
		/* use struct vring_tx_desc for Rx as well,
		 * only field used, .dma.length, is the same
		 */
		volatile struct vring_tx_desc *d =
				&vring->va[dbg_txdesc_index].tx;
				&ring->va[dbg_txdesc_index].tx.legacy;
		volatile u32 *u = (volatile u32 *)d;
		struct sk_buff *skb = vring->ctx[dbg_txdesc_index].skb;
		struct sk_buff *skb = ring->ctx[dbg_txdesc_index].skb;

		if (tx)
			seq_printf(s, "Tx[%2d][%3d] = {\n", dbg_vring_index,
			seq_printf(s, "Tx[%2d][%3d] = {\n", dbg_ring_index,
				   dbg_txdesc_index);
		else
			seq_printf(s, "Rx[%3d] = {\n", dbg_txdesc_index);
@@ -1015,11 +1016,11 @@ static int wil_txdesc_debugfs_show(struct seq_file *s, void *data)
	} else {
		if (tx)
			seq_printf(s, "[%2d] TxDesc index (%d) >= size (%d)\n",
				   dbg_vring_index, dbg_txdesc_index,
				   vring->size);
				   dbg_ring_index, dbg_txdesc_index,
				   ring->size);
		else
			seq_printf(s, "RxDesc index (%d) >= size (%d)\n",
				   dbg_txdesc_index, vring->size);
				   dbg_txdesc_index, ring->size);
	}

	return 0;
@@ -1828,7 +1829,7 @@ static const struct {
	const struct file_operations *fops;
} dbg_files[] = {
	{"mbox",	0444,		&fops_mbox},
	{"vrings",	0444,		&fops_vring},
	{"rings",	0444,		&fops_ring},
	{"stations", 0444,		&fops_sta},
	{"mids",	0444,		&fops_mids},
	{"desc",	0444,		&fops_txdesc},
@@ -1897,7 +1898,7 @@ static const struct dbg_off dbg_wil_off[] = {
	WIL_FIELD(chip_revision, 0444,	doff_u8),
	WIL_FIELD(abft_len, 0644,		doff_u8),
	WIL_FIELD(wakeup_trigger, 0644,		doff_u8),
	WIL_FIELD(vring_idle_trsh, 0644,	doff_u32),
	WIL_FIELD(ring_idle_trsh, 0644,	doff_u32),
	{},
};

@@ -1911,7 +1912,7 @@ static const struct dbg_off dbg_wil_regs[] = {
/* static parameters */
static const struct dbg_off dbg_statics[] = {
	{"desc_index",	0644, (ulong)&dbg_txdesc_index, doff_u32},
	{"vring_index",	0644, (ulong)&dbg_vring_index, doff_u32},
	{"ring_index",	0644, (ulong)&dbg_ring_index, doff_u32},
	{"mem_addr",	0644, (ulong)&mem_addr, doff_u32},
	{"led_polarity", 0644, (ulong)&led_polarity, doff_u8},
	{},
+17 −17
Original line number Diff line number Diff line
@@ -220,9 +220,9 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
	memset(sta->tid_crypto_rx, 0, sizeof(sta->tid_crypto_rx));
	memset(&sta->group_crypto_rx, 0, sizeof(sta->group_crypto_rx));
	/* release vrings */
	for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) {
		if (wil->vring2cid_tid[i][0] == cid)
			wil_vring_fini_tx(wil, i);
	for (i = 0; i < ARRAY_SIZE(wil->ring_tx); i++) {
		if (wil->ring2cid_tid[i][0] == cid)
			wil_ring_fini_tx(wil, i);
	}
	/* statistics */
	memset(&sta->stats, 0, sizeof(sta->stats));
@@ -453,12 +453,12 @@ static void wil_fw_error_worker(struct work_struct *work)
	mutex_unlock(&wil->mutex);
}

static int wil_find_free_vring(struct wil6210_priv *wil)
static int wil_find_free_ring(struct wil6210_priv *wil)
{
	int i;

	for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
		if (!wil->vring_tx[i].va)
		if (!wil->ring_tx[i].va)
			return i;
	}
	return -EINVAL;
@@ -473,13 +473,13 @@ int wil_tx_init(struct wil6210_vif *vif, int cid)
		wil_err(wil, "No connection pending\n");
		goto out;
	}
	ringid = wil_find_free_vring(wil);
	ringid = wil_find_free_ring(wil);
	if (ringid < 0) {
		wil_err(wil, "No free vring found\n");
		goto out;
	}

	wil_dbg_wmi(wil, "Configure for connection CID %d MID %d vring %d\n",
	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);
@@ -494,19 +494,19 @@ int wil_tx_init(struct wil6210_vif *vif, int cid)
int wil_bcast_init(struct wil6210_vif *vif)
{
	struct wil6210_priv *wil = vif_to_wil(vif);
	int ri = vif->bcast_vring, rc;
	int ri = vif->bcast_ring, rc;

	if ((ri >= 0) && wil->vring_tx[ri].va)
	if (ri >= 0 && wil->ring_tx[ri].va)
		return 0;

	ri = wil_find_free_vring(wil);
	ri = wil_find_free_ring(wil);
	if (ri < 0)
		return ri;

	vif->bcast_vring = ri;
	vif->bcast_ring = ri;
	rc = wil_vring_init_bcast(vif, ri, 1 << bcast_ring_order);
	if (rc)
		vif->bcast_vring = -1;
		vif->bcast_ring = -1;

	return rc;
}
@@ -514,13 +514,13 @@ int wil_bcast_init(struct wil6210_vif *vif)
void wil_bcast_fini(struct wil6210_vif *vif)
{
	struct wil6210_priv *wil = vif_to_wil(vif);
	int ri = vif->bcast_vring;
	int ri = vif->bcast_ring;

	if (ri < 0)
		return;

	vif->bcast_vring = -1;
	wil_vring_fini_tx(wil, ri);
	vif->bcast_ring = -1;
	wil_ring_fini_tx(wil, ri);
}

void wil_bcast_fini_all(struct wil6210_priv *wil)
@@ -548,7 +548,7 @@ int wil_priv_init(struct wil6210_priv *wil)
	}

	for (i = 0; i < WIL6210_MAX_TX_RINGS; i++)
		spin_lock_init(&wil->vring_tx_data[i].lock);
		spin_lock_init(&wil->ring_tx_data[i].lock);

	mutex_init(&wil->mutex);
	mutex_init(&wil->vif_mutex);
@@ -589,7 +589,7 @@ int wil_priv_init(struct wil6210_priv *wil)
	wil->wakeup_trigger = WMI_WAKEUP_TRIGGER_UCAST |
			      WMI_WAKEUP_TRIGGER_BCAST;
	memset(&wil->suspend_stats, 0, sizeof(wil->suspend_stats));
	wil->vring_idle_trsh = 16;
	wil->ring_idle_trsh = 16;

	wil->reply_mid = U8_MAX;
	wil->max_vifs = 1;
+4 −4
Original line number Diff line number Diff line
@@ -142,11 +142,11 @@ static int wil6210_netdev_poll_tx(struct napi_struct *napi, int budget)

	/* always process ALL Tx complete, regardless budget - it is fast */
	for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
		struct vring *vring = &wil->vring_tx[i];
		struct vring_tx_data *txdata = &wil->vring_tx_data[i];
		struct wil_ring *ring = &wil->ring_tx[i];
		struct wil_ring_tx_data *txdata = &wil->ring_tx_data[i];
		struct wil6210_vif *vif;

		if (!vring->va || !txdata->enabled ||
		if (!ring->va || !txdata->enabled ||
		    txdata->mid >= wil->max_vifs)
			continue;

@@ -242,7 +242,7 @@ static void wil_p2p_discovery_timer_fn(struct timer_list *t)

static void wil_vif_init(struct wil6210_vif *vif)
{
	vif->bcast_vring = -1;
	vif->bcast_ring = -1;

	mutex_init(&vif->probe_client_mutex);

+1 −1
Original line number Diff line number Diff line
@@ -389,7 +389,7 @@ int wil_addba_tx_request(struct wil6210_priv *wil, u8 ringid, u16 wsize)
{
	u8 agg_wsize = wil_agg_size(wil, wsize);
	u16 agg_timeout = 0;
	struct vring_tx_data *txdata = &wil->vring_tx_data[ringid];
	struct wil_ring_tx_data *txdata = &wil->ring_tx_data[ringid];
	int rc = 0;

	if (txdata->addba_in_progress) {
Loading