diff options
author | Vladimir Shulman <qca_shulmanv@qca.qualcomm.com> | 2015-02-15 07:02:34 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2015-02-27 03:15:19 -0500 |
commit | 0436fd9a2d1e0c87a621841ab48e779cf8f237b4 (patch) | |
tree | e28629278c1912bae7065f3c07a66e2d47111193 | |
parent | 33c477fdab257efcad139ac2a5031708aad2a1e7 (diff) |
wil6210: Change of threshold for tx vring idleness measurement
Change threshold to be variable debugfs entry from hard-coded 0.
Default threshold value is 16 descriptors because HW is capable
of fetching up to 16 descriptors at once.
Signed-off-by: Vladimir Shulman <qca_shulmanv@qca.qualcomm.com>
Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r-- | drivers/net/wireless/ath/wil6210/debugfs.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/txrx.c | 52 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/wil6210.h | 1 |
3 files changed, 39 insertions, 17 deletions
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index 3ed16e741a7e..eb6de8cbdd7a 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c | |||
@@ -29,6 +29,7 @@ | |||
29 | static u32 mem_addr; | 29 | static u32 mem_addr; |
30 | static u32 dbg_txdesc_index; | 30 | static u32 dbg_txdesc_index; |
31 | static u32 dbg_vring_index; /* 24+ for Rx, 0..23 for Tx */ | 31 | static u32 dbg_vring_index; /* 24+ for Rx, 0..23 for Tx */ |
32 | u32 vring_idle_trsh = 16; /* HW fetches up to 16 descriptors at once */ | ||
32 | 33 | ||
33 | enum dbg_off_type { | 34 | enum dbg_off_type { |
34 | doff_u32 = 0, | 35 | doff_u32 = 0, |
@@ -1412,6 +1413,8 @@ static const struct dbg_off dbg_statics[] = { | |||
1412 | {"desc_index", S_IRUGO | S_IWUSR, (ulong)&dbg_txdesc_index, doff_u32}, | 1413 | {"desc_index", S_IRUGO | S_IWUSR, (ulong)&dbg_txdesc_index, doff_u32}, |
1413 | {"vring_index", S_IRUGO | S_IWUSR, (ulong)&dbg_vring_index, doff_u32}, | 1414 | {"vring_index", S_IRUGO | S_IWUSR, (ulong)&dbg_vring_index, doff_u32}, |
1414 | {"mem_addr", S_IRUGO | S_IWUSR, (ulong)&mem_addr, doff_u32}, | 1415 | {"mem_addr", S_IRUGO | S_IWUSR, (ulong)&mem_addr, doff_u32}, |
1416 | {"vring_idle_trsh", S_IRUGO | S_IWUSR, (ulong)&vring_idle_trsh, | ||
1417 | doff_u32}, | ||
1415 | {}, | 1418 | {}, |
1416 | }; | 1419 | }; |
1417 | 1420 | ||
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 7e119d0d8454..7f2f560b8638 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c | |||
@@ -53,34 +53,38 @@ static inline int wil_vring_is_full(struct vring *vring) | |||
53 | return wil_vring_next_tail(vring) == vring->swhead; | 53 | return wil_vring_next_tail(vring) == vring->swhead; |
54 | } | 54 | } |
55 | 55 | ||
56 | /* | 56 | /* Used space in Tx Vring */ |
57 | * Available space in Tx Vring | 57 | static inline int wil_vring_used_tx(struct vring *vring) |
58 | */ | ||
59 | static inline int wil_vring_avail_tx(struct vring *vring) | ||
60 | { | 58 | { |
61 | u32 swhead = vring->swhead; | 59 | u32 swhead = vring->swhead; |
62 | u32 swtail = vring->swtail; | 60 | u32 swtail = vring->swtail; |
63 | int used = (vring->size + swhead - swtail) % vring->size; | 61 | return (vring->size + swhead - swtail) % vring->size; |
62 | } | ||
64 | 63 | ||
65 | return vring->size - used - 1; | 64 | /* Available space in Tx Vring */ |
65 | static inline int wil_vring_avail_tx(struct vring *vring) | ||
66 | { | ||
67 | return vring->size - wil_vring_used_tx(vring) - 1; | ||
66 | } | 68 | } |
67 | 69 | ||
68 | /** | 70 | /* wil_vring_wmark_low - low watermark for available descriptor space */ |
69 | * wil_vring_wmark_low - low watermark for available descriptor space | ||
70 | */ | ||
71 | static inline int wil_vring_wmark_low(struct vring *vring) | 71 | static inline int wil_vring_wmark_low(struct vring *vring) |
72 | { | 72 | { |
73 | return vring->size/8; | 73 | return vring->size/8; |
74 | } | 74 | } |
75 | 75 | ||
76 | /** | 76 | /* wil_vring_wmark_high - high watermark for available descriptor space */ |
77 | * wil_vring_wmark_high - high watermark for available descriptor space | ||
78 | */ | ||
79 | static inline int wil_vring_wmark_high(struct vring *vring) | 77 | static inline int wil_vring_wmark_high(struct vring *vring) |
80 | { | 78 | { |
81 | return vring->size/4; | 79 | return vring->size/4; |
82 | } | 80 | } |
83 | 81 | ||
82 | /* wil_val_in_range - check if value in [min,max) */ | ||
83 | static inline bool wil_val_in_range(int val, int min, int max) | ||
84 | { | ||
85 | return val >= min && val < max; | ||
86 | } | ||
87 | |||
84 | static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring) | 88 | static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring) |
85 | { | 89 | { |
86 | struct device *dev = wil_to_dev(wil); | 90 | struct device *dev = wil_to_dev(wil); |
@@ -98,8 +102,7 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring) | |||
98 | vring->va = NULL; | 102 | vring->va = NULL; |
99 | return -ENOMEM; | 103 | return -ENOMEM; |
100 | } | 104 | } |
101 | /* | 105 | /* vring->va should be aligned on its size rounded up to power of 2 |
102 | * vring->va should be aligned on its size rounded up to power of 2 | ||
103 | * This is granted by the dma_alloc_coherent | 106 | * This is granted by the dma_alloc_coherent |
104 | */ | 107 | */ |
105 | vring->va = dma_alloc_coherent(dev, sz, &vring->pa, GFP_KERNEL); | 108 | vring->va = dma_alloc_coherent(dev, sz, &vring->pa, GFP_KERNEL); |
@@ -921,6 +924,7 @@ static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
921 | struct vring_tx_data *txdata = &wil->vring_tx_data[vring_index]; | 924 | struct vring_tx_data *txdata = &wil->vring_tx_data[vring_index]; |
922 | uint i = swhead; | 925 | uint i = swhead; |
923 | dma_addr_t pa; | 926 | dma_addr_t pa; |
927 | int used; | ||
924 | 928 | ||
925 | wil_dbg_txrx(wil, "%s()\n", __func__); | 929 | wil_dbg_txrx(wil, "%s()\n", __func__); |
926 | 930 | ||
@@ -996,8 +1000,14 @@ static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
996 | */ | 1000 | */ |
997 | vring->ctx[i].skb = skb_get(skb); | 1001 | vring->ctx[i].skb = skb_get(skb); |
998 | 1002 | ||
999 | if (wil_vring_is_empty(vring)) /* performance monitoring */ | 1003 | /* performance monitoring */ |
1004 | used = wil_vring_used_tx(vring); | ||
1005 | if (wil_val_in_range(vring_idle_trsh, | ||
1006 | used, used + nr_frags + 1)) { | ||
1000 | txdata->idle += get_cycles() - txdata->last_idle; | 1007 | txdata->idle += get_cycles() - txdata->last_idle; |
1008 | wil_dbg_txrx(wil, "Ring[%2d] not idle %d -> %d\n", | ||
1009 | vring_index, used, used + nr_frags + 1); | ||
1010 | } | ||
1001 | 1011 | ||
1002 | /* advance swhead */ | 1012 | /* advance swhead */ |
1003 | wil_vring_advance_head(vring, nr_frags + 1); | 1013 | wil_vring_advance_head(vring, nr_frags + 1); |
@@ -1141,6 +1151,8 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid) | |||
1141 | int cid = wil->vring2cid_tid[ringid][0]; | 1151 | int cid = wil->vring2cid_tid[ringid][0]; |
1142 | struct wil_net_stats *stats = &wil->sta[cid].stats; | 1152 | struct wil_net_stats *stats = &wil->sta[cid].stats; |
1143 | volatile struct vring_tx_desc *_d; | 1153 | volatile struct vring_tx_desc *_d; |
1154 | int used_before_complete; | ||
1155 | int used_new; | ||
1144 | 1156 | ||
1145 | if (unlikely(!vring->va)) { | 1157 | if (unlikely(!vring->va)) { |
1146 | wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid); | 1158 | wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid); |
@@ -1154,6 +1166,8 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid) | |||
1154 | 1166 | ||
1155 | wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid); | 1167 | wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid); |
1156 | 1168 | ||
1169 | used_before_complete = wil_vring_used_tx(vring); | ||
1170 | |||
1157 | while (!wil_vring_is_empty(vring)) { | 1171 | while (!wil_vring_is_empty(vring)) { |
1158 | int new_swtail; | 1172 | int new_swtail; |
1159 | struct wil_ctx *ctx = &vring->ctx[vring->swtail]; | 1173 | struct wil_ctx *ctx = &vring->ctx[vring->swtail]; |
@@ -1215,8 +1229,12 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid) | |||
1215 | } | 1229 | } |
1216 | } | 1230 | } |
1217 | 1231 | ||
1218 | if (wil_vring_is_empty(vring)) { /* performance monitoring */ | 1232 | /* performance monitoring */ |
1219 | wil_dbg_txrx(wil, "Ring[%2d] empty\n", ringid); | 1233 | used_new = wil_vring_used_tx(vring); |
1234 | if (wil_val_in_range(vring_idle_trsh, | ||
1235 | used_new, used_before_complete)) { | ||
1236 | wil_dbg_txrx(wil, "Ring[%2d] idle %d -> %d\n", | ||
1237 | ringid, used_before_complete, used_new); | ||
1220 | txdata->last_idle = get_cycles(); | 1238 | txdata->last_idle = get_cycles(); |
1221 | } | 1239 | } |
1222 | 1240 | ||
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 85f001191319..4afb8e4bde85 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h | |||
@@ -27,6 +27,7 @@ extern bool no_fw_recovery; | |||
27 | extern unsigned int mtu_max; | 27 | extern unsigned int mtu_max; |
28 | extern unsigned short rx_ring_overflow_thrsh; | 28 | extern unsigned short rx_ring_overflow_thrsh; |
29 | extern int agg_wsize; | 29 | extern int agg_wsize; |
30 | extern u32 vring_idle_trsh; | ||
30 | 31 | ||
31 | #define WIL_NAME "wil6210" | 32 | #define WIL_NAME "wil6210" |
32 | #define WIL_FW_NAME "wil6210.fw" /* code */ | 33 | #define WIL_FW_NAME "wil6210.fw" /* code */ |