d31060d870b5fd5616a28c2065b68cbe89faaca1
[carl9170fw.git] / tools / carlu / src / test.c
1 /*
2  * carl9170user - userspace testing utility for ar9170 devices
3  *
4  * Various tests
5  *
6  * Copyright 2009, 2010 Christian Lamparter <chunkeey@googlemail.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdio.h>
28 #include <stdbool.h>
29 #include <stdlib.h>
30 #include <errno.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include "libusb.h"
34 #include "SDL.h"
35
36 #include "carlu.h"
37 #include "debug.h"
38 #include "frame.h"
39 #include "usb.h"
40 #include "cmd.h"
41
42 void debug_test(void)
43 {
44         err("This is an error.\n");
45         warn("This is a warnig.\n");
46         info("This is an informative message.\n");
47         dbg("This is just utter useless babble.\n");
48 }
49
50 void carlu_frame_test(struct carlu *ar)
51 {
52         struct frame *frame;
53
54         frame = carlu_alloc_frame(ar, 0x40);
55         frame_reserve(frame, 0x10);
56
57         memset(frame_put(frame, 0x10), 0x11, 0x10);
58         memset(frame_put(frame, 0x10), 0x22, 0x10);
59         memset(frame_push(frame, 0x10), 0x33, 0x10);
60         memset(frame_put(frame, 0x10), 0x44, 0x10);
61
62         print_hex_dump_bytes(INFO, "DATA:", frame->data, frame->len);
63
64         print_hex_dump_bytes(INFO, "PAYLOAD:", frame->payload, frame->alloced);
65
66         frame_free(frame);
67 }
68
69 static void carlu_loopback_tx_cb(struct carlu *ar __unused,
70                                     struct frame *frame __unused)
71 {
72 }
73
74 static int carlu_loopback_cmd(struct carlu *ar __unused,
75                               struct carl9170_rsp *cmd, void *buf __unused,
76                               unsigned int len __unused)
77 {
78         unsigned int i, n;
79
80         switch (cmd->hdr.cmd) {
81         case CARL9170_RSP_TXCOMP:
82                 n = cmd->hdr.ext;
83                 dbg("received tx feedback (%d).\n", n);
84
85                 for (i = 0; i < n; i++) {
86                         dbg("cookie:%x success:%d rix:%d tries:%d queue:%d\n",
87                                 cmd->tx_status[i].cookie,
88                                 cmd->tx_status[i].success,
89                                 cmd->tx_status[i].rix,
90                                 cmd->tx_status[i].tries,
91                                 cmd->tx_status[i].queue);
92                 }
93                 return -1;
94
95         default:
96                 return -1;
97         }
98 }
99
100 static void carlu_loopback_rx(struct carlu *ar,
101                                 void *buf __unused, unsigned int len)
102 {
103         ar->rxed++;
104         ar->rx_octets += len;
105 }
106
107 static void carlu_loopback_mark_tx_frames(struct frame *frame)
108 {
109         unsigned int i;
110
111         for (i = 0; i < frame->len; i++)
112                 frame->data[i] = (uint8_t) i;
113 }
114
115 void carlu_loopback_test(struct carlu *ar, const unsigned int total_runs,
116                           const unsigned int interval, const unsigned int min_len, const unsigned int max_len)
117 {
118         struct frame *frame;
119         uint32_t start_time, total_time = 0;
120         float moctets, dtime;
121         unsigned int runs = 0, i = 0, j = 0, len;
122         int ret;
123
124         if (min_len > max_len) {
125                 err("stresstest: invalid parameters => min_len:%d > max_len:%d",
126                     min_len, max_len);
127                 return;
128         }
129
130         if (min_len < 4) {
131                 err("stresstest: invalid parameters => min_len is smaller than 4");
132                 return;
133         }
134
135         len = min_len;
136         frame = carlu_alloc_frame(ar, len);
137         frame_put(frame, len);
138
139         carlu_loopback_mark_tx_frames(frame);
140
141         ar->rx_cb = carlu_loopback_rx;
142         ar->cmd_cb = carlu_loopback_cmd;
143         ar->tx_cb = carlu_loopback_tx_cb;
144
145         start_time = SDL_GetTicks();
146         while (runs <= total_runs) {
147                 if (frame && carlu_tx(ar, frame) == 0) {
148                         len = min_len;
149                         i++;
150                 } else {
151                         frame_free(frame);
152                 }
153
154                 frame = NULL;
155
156                 frame = carlu_alloc_frame(ar, len);
157                 frame_put(frame, len);
158
159                 carlu_loopback_mark_tx_frames(frame);
160                 j++;
161
162                 total_time = SDL_GetTicks() - start_time;
163
164                 if (total_time >= interval) {
165                         moctets = ((float)ar->tx_octets) / (1024.0f * 1024.0f);
166                         dtime = ((float)total_time) / 1000;
167                         info("%d: tx %d of %d => %.2f MiB in %.2f secs => %.4f MBits/s\n",
168                                 runs, i, j, moctets, dtime, (moctets * 8.0f) / dtime);
169
170                         moctets = ((float)ar->rx_octets) / (1024.0f * 1024.0f);
171                         info("%d: rx %d of %d => %.2f MiB in %.2f secs => %.4f MBits/s\n",
172                                 runs, ar->rxed, i, moctets, dtime, (moctets * 8.0f) / dtime);
173
174                         if ((ar->rxed == 0 && i) || !i) {
175                                 ret = carlu_cmd_echo(ar, 0xdeadbeef);
176                                 if (ret)
177                                         warn("firmware crashed... echo_cmd: (%d)\n", ret);
178                         }
179
180                         total_time = 0;
181                         i = 0;
182                         j = 0;
183                         ar->rxed = 0;
184                         ar->txed = 0;
185                         ar->rx_octets = 0;
186                         ar->tx_octets = 0;
187                         runs++;
188                         start_time = SDL_GetTicks();
189                 }
190         }
191
192         ar->rx_cb = NULL;
193         ar->cmd_cb = NULL;
194         ar->tx_cb = NULL;
195 }
196
197 int carlu_gpio_test(struct carlu *ar)
198 {
199         uint32_t gpio;
200
201 #define CHK(cmd)                                \
202         do {                                    \
203                 int __err;                      \
204                 if (__err = cmd)                \
205                         return __err;           \
206         } while (0)
207
208         CHK(carlu_cmd_read_mem(ar, AR9170_GPIO_REG_PORT_DATA, &gpio));
209         info("GPIO state:%x\n", gpio);
210
211         /* turn both LEDs on */
212         CHK(carlu_cmd_write_mem(ar, AR9170_GPIO_REG_PORT_DATA,
213             AR9170_GPIO_PORT_LED_0 | AR9170_GPIO_PORT_LED_1));
214
215         SDL_Delay(700);
216
217         CHK(carlu_cmd_read_mem(ar, AR9170_GPIO_REG_PORT_DATA, &gpio));
218         info("GPIO state:%x\n", gpio);
219
220         /* turn LEDs off everything */
221         CHK(carlu_cmd_write_mem(ar, AR9170_GPIO_REG_PORT_DATA, 0));
222
223         CHK(carlu_cmd_read_mem(ar, AR9170_GPIO_REG_PORT_DATA, &gpio));
224         info("GPIO state:%x\n", gpio);
225 }