blob: 4e067201232714b2a4cba15a102a91d3d0afb0c5 [file] [log] [blame]
Rachit Kankane1bc11492018-01-24 18:48:17 +05301/*
2 * Copyright (c) 2018 The Linux Foundation. All rights reserved.
3 *
Rachit Kankane1bc11492018-01-24 18:48:17 +05304 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
Rachit Kankane1bc11492018-01-24 18:48:17 +053019#include "htc_debug.h"
20#include "htc_internal.h"
21#include "htc_credit_history.h"
22#include <qdf_lock.h>
23
24struct HTC_CREDIT_HISTORY {
25 enum htc_credit_exchange_type type;
26 uint64_t time;
27 uint32_t tx_credit;
28 uint32_t htc_tx_queue_depth;
29};
30
31static qdf_spinlock_t g_htc_credit_lock;
32static uint32_t g_htc_credit_history_idx;
33static uint32_t g_htc_credit_history_length;
34static
35struct HTC_CREDIT_HISTORY htc_credit_history_buffer[HTC_CREDIT_HISTORY_MAX];
36
37
38#ifdef QCA_WIFI_NAPIER_EMULATION
39#define HTC_EMULATION_DELAY_IN_MS 20
40/**
41 * htc_add_delay(): Adds a delay in before proceeding, only for emulation
42 *
43 * Return: None
44 */
45static inline void htc_add_emulation_delay(void)
46{
47 qdf_mdelay(HTC_EMULATION_DELAY_IN_MS);
48}
49#else
50static inline void htc_add_emulation_delay(void)
51{
52}
53#endif
54
55void htc_credit_history_init(void)
56{
57 qdf_spinlock_create(&g_htc_credit_lock);
58 g_htc_credit_history_idx = 0;
59 g_htc_credit_history_length = 0;
60}
61
62/**
63 * htc_credit_record() - records tx que state & credit transactions
64 * @type: type of echange can be HTC_REQUEST_CREDIT
65 * or HTC_PROCESS_CREDIT_REPORT
66 * @tx_credits: current number of tx_credits
67 * @htc_tx_queue_depth: current hct tx queue depth
68 *
69 * This function records the credits and pending commands whenever a command is
70 * sent or credits are returned. Call this after the credits have been updated
71 * according to the transaction. Call this before dequeing commands.
72 *
73 * Consider making this function accept an HTC_ENDPOINT and find the current
74 * credits and queue depth itself.
75 *
76 */
77void htc_credit_record(enum htc_credit_exchange_type type, uint32_t tx_credit,
78 uint32_t htc_tx_queue_depth)
79{
80 qdf_spin_lock_bh(&g_htc_credit_lock);
81 if (g_htc_credit_history_idx >= HTC_CREDIT_HISTORY_MAX)
82 g_htc_credit_history_idx = 0;
83
84 htc_credit_history_buffer[g_htc_credit_history_idx].type = type;
85 htc_credit_history_buffer[g_htc_credit_history_idx].time =
86 qdf_get_log_timestamp();
87 htc_credit_history_buffer[g_htc_credit_history_idx].tx_credit =
88 tx_credit;
89 htc_credit_history_buffer[g_htc_credit_history_idx].htc_tx_queue_depth =
90 htc_tx_queue_depth;
91
92 g_htc_credit_history_idx++;
93 g_htc_credit_history_length++;
94 htc_add_emulation_delay();
95 qdf_spin_unlock_bh(&g_htc_credit_lock);
96}
97
98void htc_print_credit_history(HTC_HANDLE htc, uint32_t count,
99 qdf_abstract_print *print, void *print_priv)
100{
101 uint32_t idx;
102
103 print(print_priv, "HTC Credit History (count %u)", count);
104 qdf_spin_lock_bh(&g_htc_credit_lock);
105
106 if (count > HTC_CREDIT_HISTORY_MAX)
107 count = HTC_CREDIT_HISTORY_MAX;
108 if (count > g_htc_credit_history_length)
109 count = g_htc_credit_history_length;
110
111 /* subtract count from index, and wrap if necessary */
112 idx = HTC_CREDIT_HISTORY_MAX + g_htc_credit_history_idx - count;
113 idx %= HTC_CREDIT_HISTORY_MAX;
114
115 print(print_priv,
116 "Time (seconds) Type Credits Queue Depth");
117 while (count) {
118 struct HTC_CREDIT_HISTORY *hist =
119 &htc_credit_history_buffer[idx];
120 uint64_t secs, usecs;
121
122 qdf_log_timestamp_to_secs(hist->time, &secs, &usecs);
123 print(print_priv, "% 8lld.%06lld %-25s %-7.d %d",
124 secs,
125 usecs,
126 htc_credit_exchange_type_str(hist->type),
127 hist->tx_credit,
128 hist->htc_tx_queue_depth);
129
130 --count;
131 ++idx;
132 if (idx >= HTC_CREDIT_HISTORY_MAX)
133 idx = 0;
134 }
135
136 qdf_spin_unlock_bh(&g_htc_credit_lock);
137}