Merge "wil6210: reduce ucode_debug memory region"

This commit is contained in:
qctecmdr 2019-12-19 10:09:24 -08:00 • committed by Gerrit - the friendly Code Review server
commit 5d11e8c54c
9 changed files with 143 additions and 16 deletions

View file

@ -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,

View file

@ -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);
@ -2461,6 +2477,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),
{},
};

View file

@ -1896,6 +1896,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);

View file

@ -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)
{
@ -87,10 +94,44 @@ static int wil_stop(struct net_device *ndev)
return rc;
}
/**
* 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)
{
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))
skb->priority = 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,
};
@ -330,8 +371,12 @@ wil_vif_alloc(struct wil6210_priv *wil, const char *name,
return ERR_PTR(-EINVAL);
}
ndev = alloc_netdev(sizeof(*vif), name, name_assign_type,
wil_dev_setup);
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) {
dev_err(wil_to_dev(wil), "alloc_netdev failed\n");
return ERR_PTR(-ENOMEM);

View file

@ -1161,7 +1161,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;
@ -1174,6 +1175,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);
}
@ -1228,7 +1232,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);
@ -1397,7 +1401,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);
@ -2038,6 +2042,20 @@ err_exit:
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)
{
@ -2045,7 +2063,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;
@ -2055,6 +2072,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);
@ -2063,9 +2085,17 @@ static int __wil_tx_ring(struct wil6210_priv *wil, struct wil6210_vif *vif,
return -EINVAL;
if (unlikely(avail < 1 + nr_frags)) {
wil_err_ratelimited(wil,
"Tx ring[%2d] full. No space for %d fragments\n",
ring_index, 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;
@ -2080,6 +2110,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);
@ -2117,6 +2148,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 -
@ -2149,6 +2182,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

View file

@ -690,10 +690,12 @@ struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil,
int size, u16 ssn);
void wil_tid_ampdu_rx_free(struct wil6210_priv *wil,
struct wil_tid_ampdu_rx *r);
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);
void wil_init_txrx_ops_legacy_dma(struct wil6210_priv *wil);
void wil_tx_latency_calc(struct wil6210_priv *wil, struct sk_buff *skb,
struct wil_sta_info *sta);
int wil_get_cid_by_ring(struct wil6210_priv *wil, struct wil_ring *ring);
bool wil_is_special_packet(const struct sk_buff *skb);
#endif /* WIL6210_TXRX_H */

View file

@ -750,7 +750,7 @@ static int wil_ring_init_tx_edma(struct wil6210_vif *vif, int ring_id,
"init TX ring: ring_id=%u, cid=%u, tid=%u, sring_id=%u\n",
ring_id, cid, tid, wil->tx_sring_idx);
wil_tx_data_init(txdata);
wil_tx_data_init(wil, txdata);
ring->size = size;
rc = wil_ring_alloc_desc_ring(wil, ring, true);
if (rc)
@ -1294,6 +1294,9 @@ int wil_tx_sring_handler(struct wil6210_priv *wil,
(const void *)&msg, sizeof(msg),
false);
if (ctx->flags & WIL_CTX_FLAG_RESERVED_USED)
txdata->tx_reserved_count++;
wil_tx_desc_unmap_edma(dev,
(union wil_tx_desc *)d,
ctx);
@ -1460,7 +1463,7 @@ static int __wil_tx_ring_tso_edma(struct wil6210_priv *wil,
struct wil_ring_tx_data *txdata = &wil->ring_tx_data[ring_index];
int nr_frags = skb_shinfo(skb)->nr_frags;
int min_desc_required = nr_frags + 2; /* Headers, Head, Fragments */
int used, avail = wil_ring_avail_tx(ring);
int used, avail = wil_ring_avail_tx(ring) - txdata->tx_reserved_count;
int f, hdrlen, headlen;
int gso_type;
bool is_ipv4;
@ -1622,7 +1625,7 @@ static int wil_ring_init_bcast_edma(struct wil6210_vif *vif, int ring_id,
wil_ipa_set_bcast_sring_id(wil, sring_id);
}
wil_tx_data_init(txdata);
wil_tx_data_init(wil, txdata);
ring->size = size;
ring->is_rx = false;
rc = wil_ring_alloc_desc_ring(wil, ring, true);

View file

@ -37,6 +37,7 @@ extern bool drop_if_ring_full;
extern int n_msi;
extern uint max_assoc_sta;
extern bool drop_if_ring_full;
extern bool ac_queues;
extern uint rx_ring_order;
extern uint tx_ring_order;
extern uint bcast_ring_order;
@ -105,6 +106,7 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)
#define WIL6210_MAX_STATUS_RINGS (8)
#define WIL6210_MAX_HEADROOM_SIZE (256)
#define WIL_WMI_CALL_GENERAL_TO_MS 100
#define WIL_DEFAULT_TX_RESERVED_ENTRIES (16)
/* Hardware offload block adds the following:
* 26 bytes - 3-address QoS data header
@ -514,13 +516,17 @@ enum { /* for wil_ctx.mapped_as */
wil_mapped_as_page = 2,
};
/* for wil_ctx.flags */
#define WIL_CTX_FLAG_RESERVED_USED 0x01
/**
* struct wil_ctx - software context for ring descriptor
*/
struct wil_ctx {
struct sk_buff *skb;
u8 nr_frags;
u8 mapped_as;
u8 mapped_as:4;
u8 flags:4;
};
struct wil_desc_ring_rx_swtail { /* relevant for enhanced DMA only */
@ -654,6 +660,9 @@ struct wil_ring_tx_data {
bool addba_in_progress; /* if set, agg_xxx is for request in progress */
u8 mid;
spinlock_t lock;
u32 tx_reserved_count; /* available reserved tx entries */
u32 tx_reserved_count_used;
u32 tx_reserved_count_not_avail;
};
enum { /* for wil6210_priv.status */
@ -1110,6 +1119,8 @@ struct wil6210_priv {
struct work_struct pci_linkdown_recovery_worker;
void *ipa_handle;
u32 tx_reserved_entries; /* Used only in Talyn code-path */
};
#define wil_to_wiphy(i) (i->wiphy)

View file

@ -199,8 +199,8 @@ const struct fw_map talyn_mb_fw_mapping[] = {
{0x8c0000, 0x8c0210, 0x8c0000, "dum_user_rgf", true, true},
/* DMA OFU 296b */
{0x8c2000, 0x8c2128, 0x8c2000, "dma_ofu", true, true},
/* ucode debug 4k */
{0x8c3000, 0x8c4000, 0x8c3000, "ucode_debug", true, true},
/* ucode debug 256b */
{0x8c3000, 0x8c3100, 0x8c3000, "ucode_debug", true, true},
/* upper area 1536k */
{0x900000, 0xa80000, 0x900000, "upper", true, true},
/* UCODE areas - accessible by debugfs blobs but not by