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

Commit a3734ca9 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "wil6210: enable access category queues"

parents ee81c262 c0a75a55
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -209,6 +209,10 @@ static struct wil_config_entry config_table[] = {
			     wil_ini_param_type_signed, &agg_wsize, 0,
			     sizeof(agg_wsize), WIL_CONFIG_AGG_WSIZE_MIN,
			     WIL_CONFIG_AGG_WSIZE_MAX),
	WIL_CONFIG_INI_PARAM(WIL_CONFIG_AC_QUEUES_NAME,
			     wil_ini_param_type_unsigned, &ac_queues, 0,
			     WIL_CONFIG_BOOL_SIZE, WIL_CONFIG_BOOL_MIN,
			     WIL_CONFIG_BOOL_MAX),
	WIL_CONFIG_INI_PARAM(WIL_CONFIG_DROP_IF_FULL_NAME,
			     wil_ini_param_type_unsigned, &drop_if_ring_full,
			     0, WIL_CONFIG_BOOL_SIZE, WIL_CONFIG_BOOL_MIN,
+17 −0
Original line number Diff line number Diff line
@@ -99,6 +99,22 @@ static void wil_print_ring(struct seq_file *s, struct wil6210_priv *wil,

		v = (ring_id % 2 ? (v >> 16) : (v & 0xffff));
		seq_printf(s, "  hwhead = %u\n", v);
		if (!ring->is_rx) {
			struct wil_ring_tx_data *txdata =
				&wil->ring_tx_data[ring_id];

			seq_printf(s, "  available = %d\n",
				   wil_ring_avail_tx(ring) -
				   txdata->tx_reserved_count);
			seq_printf(s, "  used = %d\n",
				   wil_ring_used_tx(ring));
			seq_printf(s, "\n  tx_res_count = %d\n",
				   txdata->tx_reserved_count);
			seq_printf(s, "  tx_res_count_used = %d\n",
				   txdata->tx_reserved_count_used);
			seq_printf(s, "  tx_res_count_unavail = %d\n",
				   txdata->tx_reserved_count_not_avail);
		}
	}
	seq_printf(s, "  hwtail = [0x%08x] -> ", ring->hwtail);
	x = wmi_addr(wil, ring->hwtail);
@@ -2653,6 +2669,7 @@ static const struct dbg_off dbg_wil_off[] = {
	WIL_FIELD(amsdu_en, 0644,	doff_u8),
	WIL_FIELD(force_edmg_channel, 0644,	doff_u8),
	WIL_FIELD(ap_ps, 0644, doff_u8),
	WIL_FIELD(tx_reserved_entries, 0644, doff_u32),
	{},
};

+4 −0
Original line number Diff line number Diff line
@@ -1893,6 +1893,10 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
						 ftm->rx_offset);
		}

		wil->tx_reserved_entries = ((drop_if_ring_full || ac_queues) ?
					    WIL_DEFAULT_TX_RESERVED_ENTRIES :
					    0);

		if (wil->platform_ops.notify) {
			rc = wil->platform_ops.notify(wil->platform_handle,
						      WIL_PLATFORM_EVT_FW_RDY);
+48 −2
Original line number Diff line number Diff line
@@ -12,10 +12,17 @@
#include "ipa.h"
#include "config.h"

#define WIL6210_TX_QUEUES (4)

static bool alt_ifname; /* = false; */
module_param(alt_ifname, bool, 0444);
MODULE_PARM_DESC(alt_ifname, " use an alternate interface name wigigN instead of wlanN");

/* enable access category for transmit packets, this parameter may be controlled
 * via wigig.ini config file, default enabled
 */
bool ac_queues = true;

bool wil_has_other_active_ifaces(struct wil6210_priv *wil,
				 struct net_device *ndev, bool up, bool ok)
{
@@ -94,10 +101,45 @@ static int wil_do_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
	return wil_ioctl(wil, ifr->ifr_data, cmd);
}

/**
 * AC to queue mapping
 *
 * AC_VO -> queue 3
 * AC_VI -> queue 2
 * AC_BE -> queue 1
 * AC_BK -> queue 0
 */
static u16 wil_select_queue(struct net_device *ndev,
			    struct sk_buff *skb,
			    struct net_device *sb_dev,
			    select_queue_fallback_t fallback)
{
	static const u16 wil_1d_to_queue[8] = {1, 0, 0, 1, 2, 2, 3, 3};
	struct wil6210_priv *wil = ndev_to_wil(ndev);
	u16 qid;

	if (!ac_queues)
		return 0;

	/* determine the priority */
	if (wil_is_special_packet(skb))
		return 7;
	else if (skb->priority == 0 || skb->priority > 7)
		skb->priority = cfg80211_classify8021d(skb, NULL);

	qid = wil_1d_to_queue[skb->priority];

	wil_dbg_txrx(wil, "select queue for priority %d -> queue %d\n",
		     skb->priority, qid);

	return qid;
}

static const struct net_device_ops wil_netdev_ops = {
	.ndo_open		= wil_open,
	.ndo_stop		= wil_stop,
	.ndo_start_xmit		= wil_start_xmit,
	.ndo_select_queue	= wil_select_queue,
	.ndo_set_mac_address	= eth_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_do_ioctl		= wil_do_ioctl,
@@ -336,6 +378,10 @@ wil_vif_alloc(struct wil6210_priv *wil, const char *name,
		return ERR_PTR(-EINVAL);
	}

	if (ac_queues)
		ndev = alloc_netdev_mqs(sizeof(*vif), name, name_assign_type,
					wil_dev_setup, WIL6210_TX_QUEUES, 1);
	else
		ndev = alloc_netdev(sizeof(*vif), name, name_assign_type,
				    wil_dev_setup);
	if (!ndev) {
+48 −7
Original line number Diff line number Diff line
@@ -981,7 +981,8 @@ static int wil_tx_desc_map(union wil_tx_desc *desc, dma_addr_t pa,
	return 0;
}

void wil_tx_data_init(struct wil_ring_tx_data *txdata)
void wil_tx_data_init(const struct wil6210_priv *wil,
		      struct wil_ring_tx_data *txdata)
{
	spin_lock_bh(&txdata->lock);
	txdata->dot1x_open = 0;
@@ -994,6 +995,9 @@ void wil_tx_data_init(struct wil_ring_tx_data *txdata)
	txdata->agg_amsdu = 0;
	txdata->addba_in_progress = false;
	txdata->mid = U8_MAX;
	txdata->tx_reserved_count = wil->tx_reserved_entries;
	txdata->tx_reserved_count_used = 0;
	txdata->tx_reserved_count_not_avail = 0;
	spin_unlock_bh(&txdata->lock);
}

@@ -1048,7 +1052,7 @@ static int wil_vring_init_tx(struct wil6210_vif *vif, int id, int size,
		goto out;
	}

	wil_tx_data_init(txdata);
	wil_tx_data_init(wil, txdata);
	vring->is_rx = false;
	vring->size = size;
	rc = wil_vring_alloc(wil, vring);
@@ -1217,7 +1221,7 @@ int wil_vring_init_bcast(struct wil6210_vif *vif, int id, int size)
		goto out;
	}

	wil_tx_data_init(txdata);
	wil_tx_data_init(wil, txdata);
	vring->is_rx = false;
	vring->size = size;
	rc = wil_vring_alloc(wil, vring);
@@ -1858,6 +1862,20 @@ static int __wil_tx_vring_tso(struct wil6210_priv *wil, struct wil6210_vif *vif,
	return rc;
}

bool wil_is_special_packet(const struct sk_buff *skb)
{
	if (skb->protocol == cpu_to_be16(ETH_P_ARP) ||
	    skb->protocol == cpu_to_be16(ETH_P_RARP) ||
	    (skb->protocol == cpu_to_be16(ETH_P_IP) &&
	     ip_hdr(skb)->protocol == IPPROTO_ICMP) ||
	    (skb->protocol == cpu_to_be16(ETH_P_IPV6) &&
	     ipv6_hdr(skb)->nexthdr == IPPROTO_ICMPV6) ||
	    skb->protocol == cpu_to_be16(ETH_P_PAE))
		return true;

	return false;
}

static int __wil_tx_ring(struct wil6210_priv *wil, struct wil6210_vif *vif,
			 struct wil_ring *ring, struct sk_buff *skb)
{
@@ -1865,7 +1883,6 @@ static int __wil_tx_ring(struct wil6210_priv *wil, struct wil6210_vif *vif,
	struct vring_tx_desc dd, *d = ⅆ
	volatile struct vring_tx_desc *_d;
	u32 swhead = ring->swhead;
	int avail = wil_ring_avail_tx(ring);
	int nr_frags = skb_shinfo(skb)->nr_frags;
	uint f = 0;
	int ring_index = ring - wil->ring_tx;
@@ -1875,6 +1892,11 @@ static int __wil_tx_ring(struct wil6210_priv *wil, struct wil6210_vif *vif,
	int used;
	bool mcast = (ring_index == vif->bcast_ring);
	uint len = skb_headlen(skb);
	bool special_packet = (wil->tx_reserved_entries != 0 &&
			       wil_is_special_packet(skb));
	int avail = wil_ring_avail_tx(ring) -
		(special_packet ? 0 : txdata->tx_reserved_count);
	u8 ctx_flags = special_packet ? WIL_CTX_FLAG_RESERVED_USED : 0;

	wil_dbg_txrx(wil, "tx_ring: %d bytes to ring %d, nr_frags %d\n",
		     skb->len, ring_index, nr_frags);
@@ -1883,9 +1905,17 @@ static int __wil_tx_ring(struct wil6210_priv *wil, struct wil6210_vif *vif,
		return -EINVAL;

	if (unlikely(avail < 1 + nr_frags)) {
		if (special_packet) {
			txdata->tx_reserved_count_not_avail++;
			wil_err_ratelimited(wil,
					    "TX ring[%2d] full. No space for %d fragments for special packet. Tx-reserved-count is %d\n",
					    ring_index, 1 + nr_frags,
					    txdata->tx_reserved_count);
		} else {
			wil_err_ratelimited(wil,
					    "Tx ring[%2d] full. No space for %d fragments\n",
					    ring_index, 1 + nr_frags);
		}
		return -ENOMEM;
	}
	_d = &ring->va[i].tx.legacy;
@@ -1900,6 +1930,7 @@ static int __wil_tx_ring(struct wil6210_priv *wil, struct wil6210_vif *vif,
	if (unlikely(dma_mapping_error(dev, pa)))
		return -EINVAL;
	ring->ctx[i].mapped_as = wil_mapped_as_single;
	ring->ctx[i].flags = ctx_flags;
	/* 1-st segment */
	wil->txrx_ops.tx_desc_map((union wil_tx_desc *)d, pa, len,
				   ring_index);
@@ -1938,6 +1969,8 @@ static int __wil_tx_ring(struct wil6210_priv *wil, struct wil6210_vif *vif,
			goto dma_error;
		}
		ring->ctx[i].mapped_as = wil_mapped_as_page;
		ring->ctx[i].flags = ctx_flags;

		wil->txrx_ops.tx_desc_map((union wil_tx_desc *)d,
					   pa, len, ring_index);
		/* no need to check return code -
@@ -1970,6 +2003,14 @@ static int __wil_tx_ring(struct wil6210_priv *wil, struct wil6210_vif *vif,
			     ring_index, used, used + nr_frags + 1);
	}

	if (special_packet) {
		txdata->tx_reserved_count -= (f + 1);
		txdata->tx_reserved_count_used += (f + 1);
		wil_dbg_txrx(wil,
			     "Ring[%2d] tx_reserved_count: %d, reduced by %d\n",
			     ring_index, txdata->tx_reserved_count, f + 1);
	}

	/* Make sure to advance the head only after descriptor update is done.
	 * This will prevent a race condition where the completion thread
	 * will see the DU bit set from previous run and will handle the
Loading