Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>
#include <time.h>
#include <libdevmap.h>
#include <extest.h>
#include <hw/wr-streamer.h>
static struct mapping_desc *wrstm = NULL;
int read_all_stats(struct cmd_desc *cmdd, struct atom *atoms)
{
uint32_t max_latency_raw= 0, min_latency_raw=0;
double max_latency= 0, min_latency=0;
uint32_t rx_cnt= 0, tx_cnt=0, rx_cnt_lost_fr=0, rx_cnt_lost_blk=0;
uint64_t latency_acc =0;
uint32_t latency_acc_lsb=0, latency_acc_msb=0, latency_cnt=0, val=0;
int overflow=0;
double latency_avg=0;
volatile struct WR_TRANSMISSION_WB *ptr =
(volatile struct WR_TRANSMISSION_WB *)wrstm->base;
if (atoms == (struct atom *)VERBOSE_HELP) {
printf("%s - %s\n", cmdd->name, cmdd->help);
return 1;
}
//snapshot stats
ptr->SSCR1 = WR_TRANSMISSION_SSCR1_SNAPSHOT_STATS;
// min/max
max_latency_raw = ptr->RX_STAT3;
max_latency = (WR_TRANSMISSION_RX_STAT3_RX_LATENCY_MAX_R(max_latency_raw)*8)/1000.0;
min_latency_raw = ptr->RX_STAT4;
min_latency = (WR_TRANSMISSION_RX_STAT4_RX_LATENCY_MIN_R(min_latency_raw)*8)/1000.0;
//cnts
tx_cnt = ptr->TX_STAT;
rx_cnt = ptr->RX_STAT1;
rx_cnt_lost_fr = ptr->RX_STAT2;
rx_cnt_lost_blk = ptr->RX_STAT8;
//read values
latency_acc_lsb = ptr->RX_STAT5;
latency_acc_msb = ptr->RX_STAT6;
latency_cnt = ptr->RX_STAT7;
val = ptr->RX_STAT7;
overflow = (WR_TRANSMISSION_SSCR1_RX_LATENCY_ACC_OVERFLOW & val) != 0;
//put it all together
latency_acc = (((uint64_t)latency_acc_msb) << 32) | latency_acc_lsb;
latency_avg = (((double)latency_acc)*8/1000)/(double)latency_cnt;
//release snapshot
ptr->SSCR1 = 0;
fprintf(stderr, "Latency [us] : min=%10g max=%10g avg =%10g "
"(0x%x, 0x%x, %lld=%u << 32 | %u)*8/1000 us, cnt=%u)\n",
min_latency, max_latency, latency_avg, min_latency_raw,
max_latency_raw, (long long)latency_acc, latency_acc_msb,
latency_acc_lsb, latency_cnt);
fprintf(stderr, "Frames [number]: tx =%10u rx =%10u lost=%10u "
"(lost blocks%5u)\n",
tx_cnt, rx_cnt, rx_cnt_lost_fr,rx_cnt_lost_blk);
return 1;
}
#define LEAP_SECONDS 37
int read_reset_time(struct cmd_desc *cmdd, struct atom *atoms)
{
uint32_t val=0;
int days=0, hours=0, minutes=0, seconds;
double reset_time_elapsed=0;
time_t cur_time;
time_t res_time_sec;
volatile struct WR_TRANSMISSION_WB *ptr =
(volatile struct WR_TRANSMISSION_WB *)wrstm->base;
if (atoms == (struct atom *)VERBOSE_HELP) {
printf("%s - %s\n", cmdd->name, cmdd->help);
return 1;
}
val = ptr->SSCR2;
res_time_sec = (time_t)(WR_TRANSMISSION_SSCR2_RST_TS_TAI_LSB_R(val) +
LEAP_SECONDS);//to UTC
cur_time = time(NULL);
reset_time_elapsed = difftime(cur_time,res_time_sec);
days = reset_time_elapsed/(60*60*24);
hours = (reset_time_elapsed-days*60*60*24)/(60*60);
minutes = (reset_time_elapsed-days*60*60*24-hours*60*60)/(60);
seconds = (reset_time_elapsed-days*60*60*24-hours*60*60-minutes*60);
fprintf(stderr, "Time elapsed from reset: %d days, %d h, %d m, %d s; Reseted on %s\n",
days, hours, minutes, seconds, asctime(localtime(&res_time_sec)));
return 1;
}
int reset_counters(struct cmd_desc *cmdd, struct atom *atoms)
{
return 1;
}
int reset_seqid(struct cmd_desc *cmdd, struct atom *atoms)
{
return 1;
}
int set_tx_ethertype(struct cmd_desc *cmdd, struct atom *atoms)
{
return 1;
}
int set_tx_local_mac(struct cmd_desc *cmdd, struct atom *atoms)
{
return 1;
}
int set_tx_remote_mac(struct cmd_desc *cmdd, struct atom *atoms)
{
return 1;
}
int set_rx_ethertype(struct cmd_desc *cmdd, struct atom *atoms)
{
return 1;
}
int set_rx_local_mac(struct cmd_desc *cmdd, struct atom *atoms)
{
return 1;
}
int set_rx_remote_mac(struct cmd_desc *cmdd, struct atom *atoms)
{
return 1;
}
int get_set_latency(struct cmd_desc *cmdd, struct atom *atoms)
{
return 1;
}
enum wrstm_cmd_id{
WRSTM_CMD_STATS = CMD_USR,
WRSTM_CMD_RESET,
WRSTM_CMD_RESET_CNTS,
WRSTM_CMD_RESET_SEQID,
WRSTM_CMD_TX_ETHERTYPE,
WRSTM_CMD_TX_LOC_MAC,
WRSTM_CMD_TX_REM_MAC,
WRSTM_CMD_RX_ETHERTYPE,
WRSTM_CMD_RX_LOC_MAC,
WRSTM_CMD_RX_REM_MAC,
WRSTM_CMD_LATENCY,
// WRSTM_CMD_DBG_BYTE,
// WRSTM_CMD_DBG_MUX,
// WRSTM_CMD_DBG_VAL,
WRSTM_CMD_LAST,
};
#define WRSTM_CMD_NB WRSTM_CMD_LAST - CMD_USR
struct cmd_desc wrstm_cmd[WRSTM_CMD_NB + 1] = {
{ 1, WRSTM_CMD_STATS, "stats", "show all streamers statistics",
"", 0, read_all_stats},
{ 1, WRSTM_CMD_RESET, "reset",
"show time of the latest reset / time elapsed since then", "", 0,
read_reset_time},
{ 1, WRSTM_CMD_RESET_CNTS, "resetcnt",
"reset tx/rx/lost counters and avg/min/max latency values", "", 0,
reset_counters},
{ 1, WRSTM_CMD_RESET_SEQID, "resetseqid",
"reset sequence ID of the tx streamer", "", 0, reset_seqid},
{ 1, WRSTM_CMD_TX_ETHERTYPE, "txether",
"set TX ethertype", "ethertype", 1, set_tx_ethertype},
{ 1, WRSTM_CMD_TX_LOC_MAC, "txlocmac",
"set TX Local MAC addres", "mac", 1, set_tx_local_mac},
{ 1, WRSTM_CMD_TX_REM_MAC, "txremmac",
"set TX Target MAC address", "mac", 1, set_tx_remote_mac},
{ 1, WRSTM_CMD_RX_ETHERTYPE, "rxether",
"set RX ethertype", "ethertype", 1, set_rx_ethertype},
{ 1, WRSTM_CMD_RX_LOC_MAC, "rxlocmac",
"set RX Local MAC addres", "mac", 1, set_rx_local_mac},
{ 1, WRSTM_CMD_RX_REM_MAC, "rxremmac",
"set RX Remote MAC address", "mac", 1, set_rx_remote_mac},
{ 1, WRSTM_CMD_LATENCY, "lat",
"get/set config of fixed latency in integer [us] (-1 to disable)",
"[latency]", 0, get_set_latency},
// { 1, WRSTM_CMD_DBG_BYTE, "dbgbyte",
// "set which byte of the rx or tx frame should be snooped", "byte", 1,},
// { 1, WRSTM_CMD_DBG_MUX, "dbgdir",
// "set whether tx or rx frames should be snooped", "dir", 1,},
// { 1, WRSTM_CMD_DBG_VAL, "dbgword",
// "read the snooped 32-bit value", "", 0,},
{0, },
};
static void wrstm_help(char *prog)
{
fprintf(stderr, "%s [options]\n", prog);
fprintf(stderr, "%s\n", dev_mapping_help());
}
static void sig_hndl()
{
// Signal occured: free resource and exit
fprintf(stderr, "Handle signal: free resource and exit.\n");
dev_unmap(wrstm);
exit(1);
}
int main(int argc, char *argv[])
{
int ret;
struct mapping_args *map_args;
map_args = dev_parse_mapping_args(argc, argv);
if (!map_args) {
wrstm_help(argv[0]);
return -1;
}
wrstm = dev_map(map_args, sizeof(struct WR_TRANSMISSION_WB));
if (!wrstm) {
fprintf(stderr, "%s: wrstm mmap() failed: %s\n", argv[0],
strerror(errno));
free(map_args);
return -1;
}
ret = extest_register_user_cmd(wrstm_cmd, WRSTM_CMD_NB);
if (ret) {
dev_unmap(wrstm);
return -1;
}
/* execute command loop */
ret = extest_run("wrtsm", sig_hndl);
dev_unmap(wrstm);
return (ret) ? -1 : 0;
}