1 /*
2 * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
3 *
4 * 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
19 /*
20 *
21 * Permission to use, copy, modify, and/or distribute this software for any
22 * purpose with or without fee is hereby granted, provided that the above
23 * copyright notice and this permission notice appear in all copies.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
26 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
27 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
28 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
29 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
30 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
31 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
32 */
33
34 #ifndef REMOVE_PKT_LOG
35 #include "ol_txrx_types.h"
36 #include "ol_htt_tx_api.h"
37 #include "ol_tx_desc.h"
38 #include "qdf_mem.h"
39 #include "htt.h"
40 #include "htt_internal.h"
41 #include "pktlog_ac_i.h"
42 #include "wma_api.h"
43 #include "wlan_logging_sock_svc.h"
44
45 #ifdef PKTLOG_HAS_SPECIFIC_DATA
46 void
pktlog_hdr_set_specific_data(struct ath_pktlog_hdr * log_hdr,uint32_t type_specific_data)47 pktlog_hdr_set_specific_data(struct ath_pktlog_hdr *log_hdr,
48 uint32_t type_specific_data)
49 {
50 log_hdr->type_specific_data = type_specific_data;
51 }
52
53 uint32_t
pktlog_hdr_get_specific_data(struct ath_pktlog_hdr * log_hdr)54 pktlog_hdr_get_specific_data(struct ath_pktlog_hdr *log_hdr)
55 {
56 return log_hdr->type_specific_data;
57 }
58
59 void
pktlog_arg_set_specific_data(struct ath_pktlog_arg * plarg,uint32_t type_specific_data)60 pktlog_arg_set_specific_data(struct ath_pktlog_arg *plarg,
61 uint32_t type_specific_data)
62 {
63 plarg->type_specific_data = type_specific_data;
64 }
65
66 uint32_t
pktlog_arg_get_specific_data(struct ath_pktlog_arg * plarg)67 pktlog_arg_get_specific_data(struct ath_pktlog_arg *plarg)
68 {
69 return plarg->type_specific_data;
70 }
71 #endif /* PKTLOG_HAS_SPECIFIC_DATA */
72
pktlog_getbuf_intsafe(struct ath_pktlog_arg * plarg)73 void pktlog_getbuf_intsafe(struct ath_pktlog_arg *plarg)
74 {
75 struct ath_pktlog_buf *log_buf;
76 int32_t buf_size;
77 struct ath_pktlog_hdr *log_hdr;
78 int32_t cur_wr_offset;
79 char *log_ptr;
80 struct ath_pktlog_info *pl_info;
81 uint16_t log_type;
82 size_t log_size;
83 uint32_t flags;
84 #ifdef HELIUMPLUS
85 uint8_t mac_id;
86 #endif
87
88 if (!plarg) {
89 qdf_info("Invalid parg");
90 return;
91 }
92
93 pl_info = plarg->pl_info;
94 #ifdef HELIUMPLUS
95 mac_id = plarg->macId;
96 log_type = plarg->log_type;
97 #else
98 log_type = plarg->log_type;
99 #endif
100 log_size = plarg->log_size;
101 log_buf = pl_info->buf;
102 flags = plarg->flags;
103
104 if (!log_buf) {
105 qdf_info("Invalid log_buf");
106 return;
107 }
108
109
110 buf_size = pl_info->buf_size;
111 cur_wr_offset = log_buf->wr_offset;
112 /* Move read offset to the next entry if there is a buffer overlap */
113 if (log_buf->rd_offset >= 0) {
114 if ((cur_wr_offset <= log_buf->rd_offset)
115 && (cur_wr_offset + sizeof(struct ath_pktlog_hdr)) >
116 log_buf->rd_offset) {
117 PKTLOG_MOV_RD_IDX(log_buf->rd_offset, log_buf,
118 buf_size);
119 }
120 } else {
121 log_buf->rd_offset = cur_wr_offset;
122 }
123
124 log_hdr = (struct ath_pktlog_hdr *)(log_buf->log_data + cur_wr_offset);
125
126 log_hdr->flags = flags;
127 #ifdef HELIUMPLUS
128 log_hdr->macId = mac_id;
129 log_hdr->log_type = log_type;
130 #else
131 log_hdr->log_type = log_type;
132 #endif
133 log_hdr->size = (uint16_t) log_size;
134 log_hdr->missed_cnt = plarg->missed_cnt;
135 log_hdr->timestamp = plarg->timestamp;
136 pktlog_hdr_set_specific_data(log_hdr,
137 pktlog_arg_get_specific_data(plarg));
138 cur_wr_offset += sizeof(*log_hdr);
139
140 if ((buf_size - cur_wr_offset) < log_size) {
141 while ((cur_wr_offset <= log_buf->rd_offset)
142 && (log_buf->rd_offset < buf_size)) {
143 PKTLOG_MOV_RD_IDX(log_buf->rd_offset, log_buf,
144 buf_size);
145 }
146 cur_wr_offset = 0;
147 }
148
149 while ((cur_wr_offset <= log_buf->rd_offset)
150 && (cur_wr_offset + log_size) > log_buf->rd_offset) {
151 PKTLOG_MOV_RD_IDX(log_buf->rd_offset, log_buf, buf_size);
152 }
153
154 log_ptr = &(log_buf->log_data[cur_wr_offset]);
155 cur_wr_offset += log_hdr->size;
156
157 log_buf->wr_offset = ((buf_size - cur_wr_offset) >=
158 sizeof(struct ath_pktlog_hdr)) ? cur_wr_offset :
159 0;
160
161 plarg->buf = log_ptr;
162 }
163
pktlog_getbuf(struct pktlog_dev_t * pl_dev,struct ath_pktlog_info * pl_info,size_t log_size,struct ath_pktlog_hdr * pl_hdr)164 char *pktlog_getbuf(struct pktlog_dev_t *pl_dev,
165 struct ath_pktlog_info *pl_info,
166 size_t log_size, struct ath_pktlog_hdr *pl_hdr)
167 {
168 struct ath_pktlog_arg plarg = { 0, };
169 uint8_t flags = 0;
170
171 plarg.pl_info = pl_info;
172 #ifdef HELIUMPLUS
173 plarg.macId = pl_hdr->macId;
174 plarg.log_type = pl_hdr->log_type;
175 #else
176 plarg.log_type = pl_hdr->log_type;
177 #endif
178 plarg.log_size = log_size;
179 plarg.flags = pl_hdr->flags;
180 plarg.missed_cnt = pl_hdr->missed_cnt;
181 plarg.timestamp = pl_hdr->timestamp;
182 pktlog_arg_set_specific_data(&plarg,
183 pktlog_hdr_get_specific_data(pl_hdr));
184
185 if (flags & PHFLAGS_INTERRUPT_CONTEXT) {
186 /*
187 * We are already in interrupt context, no need to make it
188 * intsafe. call the function directly.
189 */
190 pktlog_getbuf_intsafe(&plarg);
191 } else {
192 PKTLOG_LOCK(pl_info);
193 pktlog_getbuf_intsafe(&plarg);
194 PKTLOG_UNLOCK(pl_info);
195 }
196
197 return plarg.buf;
198 }
199 #endif /*REMOVE_PKT_LOG */
200