blob: 0d2b8f5d28fdadcb2d360a08cf9fc677e169d732 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13/*
14 * SDIO-Abstraction-Layer Test Module.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/device.h>
20#include <linux/workqueue.h>
21#include <linux/fs.h>
22#include <linux/cdev.h>
23#include <linux/sched.h>
24#include <linux/wait.h>
25#include <linux/delay.h>
26#include <linux/slab.h>
27#include <linux/random.h>
28#include <linux/platform_device.h>
29#include <mach/sdio_smem.h>
30#include <linux/wakelock.h>
Yaniv Gardifa8b71e2011-09-06 14:00:55 +030031#include <linux/uaccess.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070032
33#include <sdio_al_private.h>
34#include <linux/debugfs.h>
35
36#include <linux/kthread.h>
37enum lpm_test_msg_type {
Yaniv Gardi3e327762011-07-27 11:11:04 +030038 LPM_NO_MSG, /* 0 */
39 LPM_MSG_SEND, /* 1 */
40 LPM_MSG_REC, /* 2 */
41 LPM_SLEEP, /* 3 */
42 LPM_WAKEUP, /* 4 */
43 LPM_NOTIFY /* 5 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070044};
45
46#define LPM_NO_MSG_NAME "LPM No Event"
47#define LPM_MSG_SEND_NAME "LPM Send Msg Event"
48#define LPM_MSG_REC_NAME "LPM Receive Msg Event"
49#define LPM_SLEEP_NAME "LPM Sleep Event"
50#define LPM_WAKEUP_NAME "LPM Wakeup Event"
51
52/** Module name string */
53#define TEST_MODULE_NAME "sdio_al_test"
54
55#define TEST_SIGNATURE 0x12345678
56#define TEST_CONFIG_SIGNATURE 0xBEEFCAFE
57
58#define MAX_XFER_SIZE (16*1024)
59#define SMEM_MAX_XFER_SIZE 0xBC000
60#define A2_MIN_PACKET_SIZE 5
Maya Erezbde9df82011-08-02 14:40:00 +030061#define DUN_PACKET_SIZE (2*1024)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070062
63#define TEST_DBG(x...) if (test_ctx->runtime_debug) pr_info(x)
64
65#define LPM_TEST_NUM_OF_PACKETS 100
Yaniv Gardi3e327762011-07-27 11:11:04 +030066#define LPM_MAX_OPEN_CHAN_PER_DEV 4
67#define LPM_ARRAY_SIZE (7*LPM_TEST_NUM_OF_PACKETS*LPM_MAX_OPEN_CHAN_PER_DEV)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070068#define SDIO_LPM_TEST "sdio_lpm_test_reading_task"
69#define LPM_TEST_CONFIG_SIGNATURE 0xDEADBABE
Yaniv Gardi3e327762011-07-27 11:11:04 +030070#define LPM_MSG_NAME_SIZE 20
Yaniv Gardifa8b71e2011-09-06 14:00:55 +030071#define MAX_STR_SIZE 10
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070072
Maya Erez53508c12011-08-01 14:04:03 +030073#define A2_HEADER_OVERHEAD 8
74
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070075enum sdio_test_case_type {
76 SDIO_TEST_LOOPBACK_HOST,
77 SDIO_TEST_LOOPBACK_CLIENT,
78 SDIO_TEST_LPM_HOST_WAKER,
79 SDIO_TEST_LPM_CLIENT_WAKER,
80 SDIO_TEST_LPM_RANDOM,
81 SDIO_TEST_HOST_SENDER_NO_LP,
Konstantin Dorfman65ac9222011-08-18 16:30:17 +030082 SDIO_TEST_CLOSE_CHANNEL,
Maya Erez53508c12011-08-01 14:04:03 +030083 /* The following tests are not part of the 9k tests and should be
84 * kept last in case new tests are added
85 */
86 SDIO_TEST_PERF,
87 SDIO_TEST_RTT,
Maya Erez8afd564f2011-08-24 15:57:06 +030088 SDIO_TEST_MODEM_RESET,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070089};
90
91struct lpm_task {
92 struct task_struct *lpm_task;
93 const char *task_name;
94};
95
96struct lpm_entry_type {
97 enum lpm_test_msg_type msg_type;
Yaniv Gardi3e327762011-07-27 11:11:04 +030098 char msg_name[LPM_MSG_NAME_SIZE];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070099 u32 counter;
100 u32 current_ms;
Yaniv Gardi3e327762011-07-27 11:11:04 +0300101 u32 read_avail_mask;
102 char chan_name[CHANNEL_NAME_SIZE];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700103};
104
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700105struct lpm_msg {
106 u32 signature;
107 u32 counter;
108 u32 reserve1;
109 u32 reserve2;
110};
111
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700112struct test_config_msg {
113 u32 signature;
114 u32 test_case;
115 u32 test_param;
116 u32 num_packets;
117 u32 num_iterations;
118};
119
120struct test_result_msg {
121 u32 signature;
122 u32 is_successful;
123};
124
125struct test_work {
126 struct work_struct work;
127 struct test_channel *test_ch;
128};
129
130enum sdio_channels_ids {
131 SDIO_RPC,
132 SDIO_QMI,
133 SDIO_RMNT,
134 SDIO_DIAG,
135 SDIO_DUN,
136 SDIO_SMEM,
137 SDIO_CIQ,
138 SDIO_MAX_CHANNELS
139};
140
141enum sdio_test_results {
142 TEST_NO_RESULT,
143 TEST_FAILED,
144 TEST_PASSED
145};
146
147enum sdio_lpm_vote_state {
148 SDIO_NO_VOTE,
149 SDIO_VOTE_FOR_SLEEP,
150 SDIO_VOTE_AGAINST_SLEEP
151};
152
Yaniv Gardi3e327762011-07-27 11:11:04 +0300153struct sdio_test_device {
154 int open_channels_counter_to_recv;
155 int open_channels_counter_to_send;
156 struct lpm_entry_type *lpm_arr;
157 int array_size;
158 void *sdio_al_device;
159 spinlock_t lpm_array_lock;
160 unsigned long lpm_array_lock_flags;
161 u32 next_avail_entry_in_array;
162 struct lpm_task lpm_test_task;
163 u32 next_mask_id;
164 u32 read_avail_mask;
165 int modem_result_per_dev;
166 int final_result_per_dev;
167};
168
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700169struct test_channel {
170 struct sdio_channel *ch;
171
172 char name[CHANNEL_NAME_SIZE];
173 int ch_id;
174
Yaniv Gardi3e327762011-07-27 11:11:04 +0300175 struct sdio_test_device *test_device;
176
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700177 u32 *buf;
178 u32 buf_size;
179
180 struct workqueue_struct *workqueue;
181 struct test_work test_work;
182
183 u32 rx_bytes;
184 u32 tx_bytes;
185
186 wait_queue_head_t wait_q;
187 atomic_t rx_notify_count;
188 atomic_t tx_notify_count;
189 atomic_t any_notify_count;
190 atomic_t wakeup_client;
Maya Erez8afd564f2011-08-24 15:57:06 +0300191 atomic_t card_detected_event;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700192
193 int wait_counter;
194
195 int is_used;
196 int test_type;
197 int ch_ready;
198
199 struct test_config_msg config_msg;
200
201 int test_completed;
202 int test_result;
203 struct timer_list timer;
204 int timer_interval_ms;
205
206 struct timer_list timeout_timer;
207 int timeout_ms;
208 void *sdio_al_device;
209 int is_ok_to_sleep;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700210 unsigned int packet_length;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700211 int random_packet_size;
Yaniv Gardi3e327762011-07-27 11:11:04 +0300212 int next_index_in_sent_msg_per_chan;
213 int channel_mask_id;
214 int modem_result_per_chan;
215 int notify_counter_per_chan;
Konstantin Dorfman65ac9222011-08-18 16:30:17 +0300216 int max_burst_size; /* number of writes before close/open */
Maya Erez8afd564f2011-08-24 15:57:06 +0300217 int card_removed;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700218};
219
220struct sdio_al_test_debug {
221 u32 dun_throughput;
222 u32 rmnt_throughput;
223 struct dentry *debug_root;
224 struct dentry *debug_test_result;
225 struct dentry *debug_dun_throughput;
226 struct dentry *debug_rmnt_throughput;
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300227 struct dentry *rpc_sender_test;
228 struct dentry *rpc_qmi_diag_sender_test;
229 struct dentry *smem_test;
230 struct dentry *smem_rpc_test;
231 struct dentry *rmnet_a2_perf_test;
232 struct dentry *dun_a2_perf_test;
233 struct dentry *rmnet_dun_a2_perf_test;
234 struct dentry *rpc_sender_rmnet_a2_perf_test;
235 struct dentry *all_channels_test;
236 struct dentry *host_sender_no_lp_diag_test;
237 struct dentry *host_sender_no_lp_diag_rpc_ciq_test;
238 struct dentry *rmnet_small_packets_test;
239 struct dentry *rmnet_rtt_test;
240 struct dentry *modem_reset_rpc_test;
241 struct dentry *modem_reset_rmnet_test;
242 struct dentry *modem_reset_channels_4bit_dev_test;
243 struct dentry *modem_reset_channels_8bit_dev_test;
244 struct dentry *modem_reset_all_channels_test;
Maya Erezefafaa82011-09-21 12:41:28 +0300245 struct dentry *open_close_test;
Maya Ereze05fc4d2011-09-11 14:18:43 +0300246 struct dentry *open_close_dun_rmnet_test;
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300247 struct dentry *close_chan_lpm_test;
248 struct dentry *lpm_test_client_wakes_host_test;
249 struct dentry *lpm_test_host_wakes_client_test;
250 struct dentry *lpm_test_random_single_channel_test;
251 struct dentry *lpm_test_random_multi_channel_test;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700252};
253
254struct test_context {
255 dev_t dev_num;
256 struct device *dev;
257 struct cdev *cdev;
Yaniv Gardi3e327762011-07-27 11:11:04 +0300258 int number_of_active_devices;
259 int max_number_of_devices;
260
261 struct sdio_test_device test_dev_arr[MAX_NUM_OF_SDIO_DEVICES];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700262
263 struct test_channel *test_ch;
264
265 struct test_channel *test_ch_arr[SDIO_MAX_CHANNELS];
266
267 long testcase;
268
269 const char *name;
270
271 int exit_flag;
272
273 u32 signature;
274
275 int runtime_debug;
276
Maya Erezefafaa82011-09-21 12:41:28 +0300277 struct platform_device *smem_pdev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700278 struct sdio_smem_client *sdio_smem;
279 int smem_was_init;
280 u8 *smem_buf;
Maya Erezefafaa82011-09-21 12:41:28 +0300281 uint32_t smem_counter;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700282
283 wait_queue_head_t wait_q;
284 int test_completed;
285 int test_result;
286 struct sdio_al_test_debug debug;
287
288 struct wake_lock wake_lock;
Maya Erezf204e692011-08-12 22:00:13 +0300289
290 unsigned int lpm_pseudo_random_seed;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700291};
292
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300293/* FORWARD DECLARATIONS */
294static int set_params_loopback_9k(struct test_channel *tch);
295static int set_params_smem_test(struct test_channel *tch);
296static int set_params_a2_perf(struct test_channel *tch);
297static int set_params_8k_sender_no_lp(struct test_channel *tch);
298static int set_params_a2_small_pkts(struct test_channel *tch);
299static int set_params_rtt(struct test_channel *tch);
300static int set_params_loopback_9k_close(struct test_channel *tch);
Yaniv Gardib4237782011-08-31 20:06:16 +0300301static int close_channel_lpm_test(int channel_num);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300302static int set_params_lpm_test(struct test_channel *tch,
303 enum sdio_test_case_type test,
304 int timer_interval_ms);
305static void set_pseudo_random_seed(void);
306static int set_params_modem_reset(struct test_channel *tch);
307static int test_start(void);
Yaniv Gardi9263c212011-08-31 20:37:45 +0300308static void rx_cleanup(struct test_channel *test_ch, int *rx_packet_count);
309static void sdio_al_test_cleanup_channels(void);
Maya Erezefafaa82011-09-21 12:41:28 +0300310static void notify(void *priv, unsigned channel_event);
311#ifdef CONFIG_MSM_SDIO_SMEM
312static int sdio_smem_open(struct sdio_smem_client *sdio_smem);
313#endif
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300314
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700315/*
316 * Seed for pseudo random time sleeping in Random LPM test.
317 * If not set, current time in jiffies is used.
318 */
319static unsigned int seed;
320module_param(seed, int, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700321static struct test_context *test_ctx;
322
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300323static void sdio_al_test_initial_dev_and_chan(struct test_context *test_ctx)
324{
Yaniv Gardi9263c212011-08-31 20:37:45 +0300325 int i = 0;
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300326
Yaniv Gardi9263c212011-08-31 20:37:45 +0300327 for (i = 0 ; i < MAX_NUM_OF_SDIO_DEVICES ; ++i)
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300328 test_ctx->test_dev_arr[i].sdio_al_device = NULL;
329
Yaniv Gardi9263c212011-08-31 20:37:45 +0300330 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300331 struct test_channel *tch = test_ctx->test_ch_arr[i];
332 if (!tch)
333 continue;
334 tch->is_used = 0;
335 }
Yaniv Gardi9263c212011-08-31 20:37:45 +0300336
337 sdio_al_test_cleanup_channels();
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300338}
339
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700340#ifdef CONFIG_DEBUG_FS
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300341
342static int message_repeat;
343
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300344static int sdio_al_test_extract_number(const char __user *buf,
345 size_t count)
346{
347 int ret = 0;
348 int number = -1;
349 char local_buf[MAX_STR_SIZE] = {0};
350 char *start = NULL;
351
352 if (count > MAX_STR_SIZE) {
353 pr_err(TEST_MODULE_NAME ": %s - MAX_STR_SIZE(%d) < count(%d). "
354 "Please choose smaller number\n",
355 __func__, MAX_STR_SIZE, (int)count);
356 return -EINVAL;
357 }
358
359 if (copy_from_user(local_buf, buf, count)) {
360 pr_err(TEST_MODULE_NAME ": %s - copy_from_user() failed\n",
361 __func__);
362 return -EINVAL;
363 }
364
365 /* adding null termination to the string */
366 local_buf[count] = '\0';
367
368 /* stripping leading and trailing white spaces */
369 start = strstrip(local_buf);
370
371 ret = kstrtoint(start, 10, &number);
372
373 if (ret) {
374 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
375 __func__);
376 return ret;
377 }
378
379 return number;
380}
381
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300382static int sdio_al_test_open(struct inode *inode, struct file *file)
383{
384 file->private_data = inode->i_private;
385 message_repeat = 1;
386 return 0;
387}
388
Yaniv Gardi9263c212011-08-31 20:37:45 +0300389static void sdio_al_test_cleanup_channels(void)
390{
391 int channel_num;
392 int dummy = 0;
393
394 for (channel_num = 0 ; channel_num < SDIO_MAX_CHANNELS ;
395 ++channel_num) {
396 if (channel_num == SDIO_SMEM)
397 continue;
398
399 rx_cleanup(test_ctx->test_ch_arr[channel_num], &dummy);
400 }
401
402 return;
403}
404
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300405/* RPC SENDER TEST */
406static ssize_t rpc_sender_test_write(struct file *file,
407 const char __user *buf,
408 size_t count,
409 loff_t *ppos)
410{
411 int ret = 0;
412 int i = 0;
413 int number = -1;
414
415 pr_info(TEST_MODULE_NAME "-- RPC SENDER TEST --\n");
416
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300417 number = sdio_al_test_extract_number(buf, count);
418
419 if (number < 0) {
420 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
421 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300422 return count;
423 }
424
425 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300426 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
427 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300428
429 sdio_al_test_initial_dev_and_chan(test_ctx);
430
431 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
432
433 ret = test_start();
434
435 if (ret)
436 break;
437 }
438
439 return count;
440}
441
442static ssize_t rpc_sender_test_read(struct file *file,
443 char __user *buffer,
444 size_t count,
445 loff_t *offset)
446{
447 memset((void *)buffer, 0, count);
448
449 snprintf(buffer, count,
450 "\nRPC_SENDER_TEST\n"
451 "===============\n"
452 "Description:\n"
453 "TBD\n");
454
455 if (message_repeat == 1) {
456 message_repeat = 0;
457 return strnlen(buffer, count);
458 } else {
459 return 0;
460 }
461}
462
463const struct file_operations rpc_sender_test_ops = {
464 .open = sdio_al_test_open,
465 .write = rpc_sender_test_write,
466 .read = rpc_sender_test_read,
467};
468
469/* RPC, QMI & DIAG SENDER TEST */
470static ssize_t rpc_qmi_diag_sender_test_write(struct file *file,
471 const char __user *buf,
472 size_t count,
473 loff_t *ppos)
474{
475 int ret = 0;
476 int i = 0;
477 int number = -1;
478
479 pr_info(TEST_MODULE_NAME "-- RPC, QMI AND DIAG SENDER TEST --\n");
480
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300481 number = sdio_al_test_extract_number(buf, count);
482
483 if (number < 0) {
484 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
485 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300486 return count;
487 }
488
489 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300490 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
491 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300492
493 sdio_al_test_initial_dev_and_chan(test_ctx);
494
495 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
496 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_QMI]);
497 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_DIAG]);
498
499 ret = test_start();
500
501 if (ret)
502 break;
503 }
504
505 return count;
506}
507
508static ssize_t rpc_qmi_diag_sender_test_read(struct file *file,
509 char __user
510 *buffer, size_t count,
511 loff_t *offset)
512{
513 memset((void *)buffer, 0, count);
514
515 snprintf(buffer, count,
516 "\nRPC_QMI_DIAG_SENDER_TEST\n"
517 "========================\n"
518 "Description:\n"
519 "TBD\n");
520
521
522 if (message_repeat == 1) {
523 message_repeat = 0;
524 return strnlen(buffer, count);
525 } else {
526 return 0;
527 }
528}
529
530const struct file_operations rpc_qmi_diag_sender_test_ops = {
531 .open = sdio_al_test_open,
532 .write = rpc_qmi_diag_sender_test_write,
533 .read = rpc_qmi_diag_sender_test_read,
534};
535
536/* SMEM TEST */
537static ssize_t smem_test_write(struct file *file,
538 const char __user *buf,
539 size_t count,
540 loff_t *ppos)
541{
542 int ret = 0;
543 int i = 0;
544 int number = -1;
545
546 pr_info(TEST_MODULE_NAME "-- SMEM TEST --\n");
547
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300548 number = sdio_al_test_extract_number(buf, count);
549
550 if (number < 0) {
551 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
552 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300553 return count;
554 }
555
556 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300557 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
558 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300559
560 sdio_al_test_initial_dev_and_chan(test_ctx);
561
562 set_params_smem_test(test_ctx->test_ch_arr[SDIO_SMEM]);
563
564 ret = test_start();
565
566 if (ret)
567 break;
568 }
569
570 return count;
571}
572
573static ssize_t smem_test_read(struct file *file,
574 char __user *buffer,
575 size_t count,
576 loff_t *offset)
577{
578 memset((void *)buffer, 0, count);
579
580 snprintf(buffer, count,
581 "\nSMEM_TEST\n"
582 "=========\n"
583 "Description:\n"
584 "TBD\n");
585
586 if (message_repeat == 1) {
587 message_repeat = 0;
588 return strnlen(buffer, count);
589 } else {
590 return 0;
591 }
592}
593
594const struct file_operations smem_test_ops = {
595 .open = sdio_al_test_open,
596 .write = smem_test_write,
597 .read = smem_test_read,
598};
599
600/* SMEM & RPC TEST */
601static ssize_t smem_rpc_test_write(struct file *file,
602 const char __user *buf,
603 size_t count,
604 loff_t *ppos)
605{
606 int ret = 0;
607 int i = 0;
608 int number = -1;
609
610 pr_info(TEST_MODULE_NAME "-- SMEM AND RPC TEST --\n");
611
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300612 number = sdio_al_test_extract_number(buf, count);
613
614 if (number < 0) {
615 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
616 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300617 return count;
618 }
619
620 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300621 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
622 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300623
624 sdio_al_test_initial_dev_and_chan(test_ctx);
625
626 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
627 set_params_smem_test(test_ctx->test_ch_arr[SDIO_SMEM]);
628
629 ret = test_start();
630
631 if (ret)
632 break;
633 }
634
635 return count;
636}
637
638static ssize_t smem_rpc_test_read(struct file *file,
639 char __user *buffer,
640 size_t count,
641 loff_t *offset)
642{
643 memset((void *)buffer, 0, count);
644
645 snprintf(buffer, count,
646 "\nSMEM_RPC_TEST\n"
647 "=============\n"
648 "Description:\n"
649 "TBD\n");
650
651 if (message_repeat == 1) {
652 message_repeat = 0;
653 return strnlen(buffer, count);
654 } else {
655 return 0;
656 }
657}
658
659const struct file_operations smem_rpc_test_ops = {
660 .open = sdio_al_test_open,
661 .write = smem_rpc_test_write,
662 .read = smem_rpc_test_read,
663};
664
665/* RMNET A2 PERFORMANCE TEST */
666static ssize_t rmnet_a2_perf_test_write(struct file *file,
667 const char __user *buf,
668 size_t count,
669 loff_t *ppos)
670{
671 int ret = 0;
672 int i = 0;
673 int number = -1;
674
675 pr_info(TEST_MODULE_NAME "-- RMNET A2 PERFORMANCE TEST --\n");
676
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300677 number = sdio_al_test_extract_number(buf, count);
678
679 if (number < 0) {
680 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
681 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300682 return count;
683 }
684
685 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300686 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
687 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300688
689 sdio_al_test_initial_dev_and_chan(test_ctx);
690
691 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
692
693 ret = test_start();
694
695 if (ret)
696 break;
697 }
698
699 return count;
700}
701
702static ssize_t rmnet_a2_perf_test_read(struct file *file,
703 char __user *buffer,
704 size_t count,
705 loff_t *offset)
706{
707 memset((void *)buffer, 0, count);
708
709 snprintf(buffer, count,
710 "\nRMNET_A2_PERFORMANCE_TEST\n"
711 "=========================\n"
712 "Description:\n"
713 "TBD\n");
714
715 if (message_repeat == 1) {
716 message_repeat = 0;
717 return strnlen(buffer, count);
718 } else {
719 return 0;
720 }
721}
722
723const struct file_operations rmnet_a2_perf_test_ops = {
724 .open = sdio_al_test_open,
725 .write = rmnet_a2_perf_test_write,
726 .read = rmnet_a2_perf_test_read,
727};
728
729/* DUN A2 PERFORMANCE TEST */
730static ssize_t dun_a2_perf_test_write(struct file *file,
731 const char __user *buf,
732 size_t count,
733 loff_t *ppos)
734{
735 int ret = 0;
736 int i = 0;
737 int number = -1;
738
739 pr_info(TEST_MODULE_NAME "-- DUN A2 PERFORMANCE TEST --\n");
740
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300741 number = sdio_al_test_extract_number(buf, count);
742
743 if (number < 0) {
744 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
745 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300746 return count;
747 }
748
749 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300750 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
751 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300752
753 sdio_al_test_initial_dev_and_chan(test_ctx);
754
755 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_DUN]);
756
757 ret = test_start();
758
759 if (ret)
760 break;
761 }
762
763 return count;
764}
765
766static ssize_t dun_a2_perf_test_read(struct file *file,
767 char __user *buffer,
768 size_t count,
769 loff_t *offset)
770{
771 memset((void *)buffer, 0, count);
772
773 snprintf(buffer, count,
774 "\nDUN_A2_PERFORMANCE_TEST\n"
775 "=======================\n"
776 "Description:\n"
777 "TBD\n");
778
779 if (message_repeat == 1) {
780 message_repeat = 0;
781 return strnlen(buffer, count);
782 } else {
783 return 0;
784 }
785}
786
787const struct file_operations dun_a2_perf_test_ops = {
788 .open = sdio_al_test_open,
789 .write = dun_a2_perf_test_write,
790 .read = dun_a2_perf_test_read,
791};
792
793/* RMNET DUN A2 PERFORMANCE TEST */
794static ssize_t rmnet_dun_a2_perf_test_write(struct file *file,
795 const char __user *buf,
796 size_t count,
797 loff_t *ppos)
798{
799 int ret = 0;
800 int i = 0;
801 int number = -1;
802
803 pr_info(TEST_MODULE_NAME "-- RMNET AND DUN A2 PERFORMANCE TEST --\n");
804
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300805 number = sdio_al_test_extract_number(buf, count);
806
807 if (number < 0) {
808 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
809 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300810 return count;
811 }
812
813 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300814 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
815 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300816
817 sdio_al_test_initial_dev_and_chan(test_ctx);
818
819 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
820 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_DUN]);
821
822 ret = test_start();
823
824 if (ret)
825 break;
826 }
827
828 return count;
829}
830
831static ssize_t rmnet_dun_a2_perf_test_read(struct file *file,
832 char __user *buffer,
833 size_t count,
834 loff_t *offset)
835{
836 memset((void *)buffer, 0, count);
837
838 snprintf(buffer, count,
839 "\nRMNET_DUN_A2_PERFORMANCE_TEST\n"
840 "=============================\n"
841 "Description:\n"
842 "TBD\n");
843
844 if (message_repeat == 1) {
845 message_repeat = 0;
846 return strnlen(buffer, count);
847 } else {
848 return 0;
849 }
850}
851
852const struct file_operations rmnet_dun_a2_perf_test_ops = {
853 .open = sdio_al_test_open,
854 .write = rmnet_dun_a2_perf_test_write,
855 .read = rmnet_dun_a2_perf_test_read,
856};
857
858/* RPC SENDER & RMNET A2 PERFORMANCE TEST */
859static ssize_t rpc_sender_rmnet_a2_perf_test_write(struct file *file,
860 const char __user *buf,
861 size_t count,
862 loff_t *ppos)
863{
864 int ret = 0;
865 int i = 0;
866 int number = -1;
867
868 pr_info(TEST_MODULE_NAME "--RPC SENDER AND RMNET A2 "
869 "PERFORMANCE --\n");
870
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300871 number = sdio_al_test_extract_number(buf, count);
872
873 if (number < 0) {
874 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
875 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300876 return count;
877 }
878
879 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300880 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
881 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300882
883 sdio_al_test_initial_dev_and_chan(test_ctx);
884
885 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
886 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
887
888 ret = test_start();
889
890 if (ret)
891 break;
892 }
893
894 return count;
895}
896
897static ssize_t rpc_sender_rmnet_a2_perf_test_read(struct file *file,
898 char __user *buffer,
899 size_t count,
900 loff_t *offset)
901{
902 memset((void *)buffer, 0, count);
903
904 snprintf(buffer, count,
905 "\nRPC_SENDER_RMNET_A2_PERFORMANCE_TEST\n"
906 "====================================\n"
907 "Description:\n"
908 "TBD\n");
909
910 if (message_repeat == 1) {
911 message_repeat = 0;
912 return strnlen(buffer, count);
913 } else {
914 return 0;
915 }
916}
917
918const struct file_operations rpc_sender_rmnet_a2_perf_test_ops = {
919 .open = sdio_al_test_open,
920 .write = rpc_sender_rmnet_a2_perf_test_write,
921 .read = rpc_sender_rmnet_a2_perf_test_read,
922};
923
924/* ALL CHANNELS TEST */
925static ssize_t all_channels_test_write(struct file *file,
926 const char __user *buf,
927 size_t count,
928 loff_t *ppos)
929{
930 int ret = 0;
931 int i = 0;
932 int number = -1;
933
934 pr_info(TEST_MODULE_NAME "-- ALL THE CHANNELS TEST --\n");
935
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300936 number = sdio_al_test_extract_number(buf, count);
937
938 if (number < 0) {
939 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
940 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300941 return count;
942 }
943
944 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300945 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
946 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300947
948 sdio_al_test_initial_dev_and_chan(test_ctx);
949
950 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
951 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_QMI]);
952 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_DIAG]);
953 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
954 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_DUN]);
955 set_params_smem_test(test_ctx->test_ch_arr[SDIO_SMEM]);
956 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_CIQ]);
957
958 ret = test_start();
959
960 if (ret)
961 break;
962 }
963
964 return count;
965}
966
967static ssize_t all_channels_test_read(struct file *file,
968 char __user *buffer,
969 size_t count,
970 loff_t *offset)
971{
972 memset((void *)buffer, 0, count);
973
974 snprintf(buffer, count,
975 "\nALL_CHANNELS_TEST\n"
976 "=================\n"
977 "Description:\n"
978 "TBD\n");
979
980 if (message_repeat == 1) {
981 message_repeat = 0;
982 return strnlen(buffer, count);
983 } else {
984 return 0;
985 }
986}
987
988const struct file_operations all_channels_test_ops = {
989 .open = sdio_al_test_open,
990 .write = all_channels_test_write,
991 .read = all_channels_test_read,
992};
993
994/* HOST SENDER NO LP DIAG TEST */
995static ssize_t host_sender_no_lp_diag_test_write(struct file *file,
996 const char __user *buf,
997 size_t count,
998 loff_t *ppos)
999{
1000 int ret = 0;
1001 int i = 0;
1002 int number = -1;
1003
1004 pr_info(TEST_MODULE_NAME "-- HOST SENDER NO LP FOR DIAG TEST --");
1005
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001006 number = sdio_al_test_extract_number(buf, count);
1007
1008 if (number < 0) {
1009 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1010 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001011 return count;
1012 }
1013
1014 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001015 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1016 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001017
1018 sdio_al_test_initial_dev_and_chan(test_ctx);
1019
1020 set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_DIAG]);
1021
1022 ret = test_start();
1023
1024 if (ret)
1025 break;
1026 }
1027
1028 return count;
1029}
1030
1031static ssize_t host_sender_no_lp_diag_test_read(struct file *file,
1032 char __user *buffer,
1033 size_t count,
1034 loff_t *offset)
1035{
1036 memset((void *)buffer, 0, count);
1037
1038 snprintf(buffer, count,
1039 "\nHOST_SENDER_NO_LP_DIAG_TEST\n"
1040 "===========================\n"
1041 "Description:\n"
1042 "TBD\n");
1043
1044 if (message_repeat == 1) {
1045 message_repeat = 0;
1046 return strnlen(buffer, count);
1047 } else {
1048 return 0;
1049 }
1050}
1051
1052const struct file_operations host_sender_no_lp_diag_test_ops = {
1053 .open = sdio_al_test_open,
1054 .write = host_sender_no_lp_diag_test_write,
1055 .read = host_sender_no_lp_diag_test_read,
1056};
1057
1058/* HOST SENDER NO LP DIAG, RPC, CIQ TEST */
1059static ssize_t host_sender_no_lp_diag_rpc_ciq_test_write(
1060 struct file *file,
1061 const char __user *buf,
1062 size_t count,
1063 loff_t *ppos)
1064{
1065 int ret = 0;
1066 int i = 0;
1067 int number = -1;
1068
1069 pr_info(TEST_MODULE_NAME "-- HOST SENDER NO LP FOR DIAG, RPC, "
1070 "CIQ TEST --");
1071
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001072 number = sdio_al_test_extract_number(buf, count);
1073
1074 if (number < 0) {
1075 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1076 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001077 return count;
1078 }
1079
1080 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001081 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1082 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001083
1084 sdio_al_test_initial_dev_and_chan(test_ctx);
1085
1086 set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_DIAG]);
1087 set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_CIQ]);
1088 set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_RPC]);
1089
1090 ret = test_start();
1091
1092 if (ret)
1093 break;
1094 }
1095
1096 return count;
1097}
1098
1099static ssize_t host_sender_no_lp_diag_rpc_ciq_test_read(
1100 struct file *file,
1101 char __user *buffer,
1102 size_t count,
1103 loff_t *offset)
1104{
1105 memset((void *)buffer, 0, count);
1106
1107 snprintf(buffer, count,
1108 "\nHOST_SENDER_NO_LP_DIAG_RPC_CIQ_TEST\n"
1109 "===================================\n"
1110 "Description:\n"
1111 "TBD\n");
1112
1113 if (message_repeat == 1) {
1114 message_repeat = 0;
1115 return strnlen(buffer, count);
1116 } else {
1117 return 0;
1118 }
1119}
1120
1121const struct file_operations host_sender_no_lp_diag_rpc_ciq_test_ops = {
1122 .open = sdio_al_test_open,
1123 .write = host_sender_no_lp_diag_rpc_ciq_test_write,
1124 .read = host_sender_no_lp_diag_rpc_ciq_test_read,
1125};
1126
1127/* RMNET SMALL PACKETS TEST */
1128static ssize_t rmnet_small_packets_test_write(struct file *file,
1129 const char __user *buf,
1130 size_t count,
1131 loff_t *ppos)
1132{
1133 int ret = 0;
1134 int i = 0;
1135 int number = -1;
1136
1137 pr_info(TEST_MODULE_NAME "-- RMNET SMALL PACKETS (5-128) TEST --");
1138
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001139 number = sdio_al_test_extract_number(buf, count);
1140
1141 if (number < 0) {
1142 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1143 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001144 return count;
1145 }
1146
1147 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001148 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1149 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001150
1151 sdio_al_test_initial_dev_and_chan(test_ctx);
1152
1153 set_params_a2_small_pkts(test_ctx->test_ch_arr[SDIO_RMNT]);
1154
1155 ret = test_start();
1156
1157 if (ret)
1158 break;
1159 }
1160
1161 return count;
1162}
1163
1164static ssize_t rmnet_small_packets_test_read(struct file *file,
1165 char __user *buffer,
1166 size_t count,
1167 loff_t *offset)
1168{
1169 memset((void *)buffer, 0, count);
1170
1171 snprintf(buffer, count,
1172 "\nRMNET_SMALL_PACKETS_TEST\n"
1173 "========================\n"
1174 "Description:\n"
1175 "TBD\n");
1176
1177 if (message_repeat == 1) {
1178 message_repeat = 0;
1179 return strnlen(buffer, count);
1180 } else {
1181 return 0;
1182 }
1183}
1184
1185const struct file_operations rmnet_small_packets_test_ops = {
1186 .open = sdio_al_test_open,
1187 .write = rmnet_small_packets_test_write,
1188 .read = rmnet_small_packets_test_read,
1189};
1190
1191/* RMNET RTT TEST */
1192static ssize_t rmnet_rtt_test_write(struct file *file,
1193 const char __user *buf,
1194 size_t count,
1195 loff_t *ppos)
1196{
1197 int ret = 0;
1198 int i = 0;
1199 int number = -1;
1200
1201 pr_info(TEST_MODULE_NAME "-- RMNET RTT TEST --");
1202
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001203 number = sdio_al_test_extract_number(buf, count);
1204
1205 if (number < 0) {
1206 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1207 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001208 return count;
1209 }
1210
1211 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001212 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1213 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001214
1215 sdio_al_test_initial_dev_and_chan(test_ctx);
1216
1217 set_params_rtt(test_ctx->test_ch_arr[SDIO_RMNT]);
1218
1219 ret = test_start();
1220
1221 if (ret)
1222 break;
1223 }
1224
1225 return count;
1226}
1227
1228static ssize_t rmnet_rtt_test_read(struct file *file,
1229 char __user *buffer,
1230 size_t count,
1231 loff_t *offset)
1232{
1233 memset((void *)buffer, 0, count);
1234
1235 snprintf(buffer, count,
1236 "\nRMNET_RTT_TEST\n"
1237 "==============\n"
1238 "Description:\n"
1239 "TBD\n");
1240
1241 if (message_repeat == 1) {
1242 message_repeat = 0;
1243 return strnlen(buffer, count);
1244 } else {
1245 return 0;
1246 }
1247}
1248
1249const struct file_operations rmnet_rtt_test_ops = {
1250 .open = sdio_al_test_open,
1251 .write = rmnet_rtt_test_write,
1252 .read = rmnet_rtt_test_read,
1253};
1254
1255/* MODEM RESET RPC TEST */
1256static ssize_t modem_reset_rpc_test_write(struct file *file,
1257 const char __user *buf,
1258 size_t count,
1259 loff_t *ppos)
1260{
1261 int ret = 0;
1262 int i = 0;
1263 int number = -1;
1264
1265 pr_info(TEST_MODULE_NAME "-- MODEM RESET - RPC CHANNEL TEST --");
1266
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001267 number = sdio_al_test_extract_number(buf, count);
1268
1269 if (number < 0) {
1270 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1271 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001272 return count;
1273 }
1274
1275 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001276 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1277 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001278
1279 sdio_al_test_initial_dev_and_chan(test_ctx);
1280
1281 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RPC]);
1282
1283 ret = test_start();
1284
1285 if (ret)
1286 break;
1287 }
1288
1289 return count;
1290}
1291
1292static ssize_t modem_reset_rpc_test_read(struct file *file,
1293 char __user *buffer,
1294 size_t count,
1295 loff_t *offset)
1296{
1297 memset((void *)buffer, 0, count);
1298
1299 snprintf(buffer, count,
1300 "\nMODEM_RESET_RPC_TEST\n"
1301 "====================\n"
1302 "Description:\n"
1303 "TBD\n");
1304
1305 if (message_repeat == 1) {
1306 message_repeat = 0;
1307 return strnlen(buffer, count);
1308 } else {
1309 return 0;
1310 }
1311}
1312
1313const struct file_operations modem_reset_rpc_test_ops = {
1314 .open = sdio_al_test_open,
1315 .write = modem_reset_rpc_test_write,
1316 .read = modem_reset_rpc_test_read,
1317};
1318
1319/* MODEM RESET RMNET TEST */
1320static ssize_t modem_reset_rmnet_test_write(struct file *file,
1321 const char __user *buf,
1322 size_t count,
1323 loff_t *ppos)
1324{
1325 int ret = 0;
1326 int i = 0;
1327 int number = -1;
1328
1329 pr_info(TEST_MODULE_NAME "-- MODEM RESET - RMNT CHANNEL TEST --");
1330
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001331 number = sdio_al_test_extract_number(buf, count);
1332
1333 if (number < 0) {
1334 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1335 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001336 return count;
1337 }
1338
1339 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001340 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1341 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001342
1343 sdio_al_test_initial_dev_and_chan(test_ctx);
1344
1345 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]);
1346
1347 ret = test_start();
1348
1349 if (ret)
1350 break;
1351 }
1352
1353 return count;
1354}
1355
1356static ssize_t modem_reset_rmnet_test_read(struct file *file,
1357 char __user *buffer,
1358 size_t count,
1359 loff_t *offset)
1360{
1361 memset((void *)buffer, 0, count);
1362
1363 snprintf(buffer, count,
1364 "\nMODEM_RESET_RMNET_TEST\n"
1365 "======================\n"
1366 "Description:\n"
1367 "TBD\n");
1368
1369 if (message_repeat == 1) {
1370 message_repeat = 0;
1371 return strnlen(buffer, count);
1372 } else {
1373 return 0;
1374 }
1375}
1376
1377const struct file_operations modem_reset_rmnet_test_ops = {
1378 .open = sdio_al_test_open,
1379 .write = modem_reset_rmnet_test_write,
1380 .read = modem_reset_rmnet_test_read,
1381};
1382
1383/* MODEM RESET - CHANNELS IN 4BIT DEVICE TEST */
1384static ssize_t modem_reset_channels_4bit_dev_test_write(
1385 struct file *file,
1386 const char __user *buf,
1387 size_t count,
1388 loff_t *ppos)
1389{
1390 int ret = 0;
1391 int i = 0;
1392 int number = -1;
1393
1394 pr_info(TEST_MODULE_NAME "-- MODEM RESET - ALL CHANNELS IN "
1395 "4BIT DEVICE TEST --");
1396
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001397 number = sdio_al_test_extract_number(buf, count);
1398
1399 if (number < 0) {
1400 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1401 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001402 return count;
1403 }
1404
1405 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001406 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1407 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001408
1409 sdio_al_test_initial_dev_and_chan(test_ctx);
1410
1411 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RPC]);
1412 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_QMI]);
1413 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DIAG]);
1414
1415 ret = test_start();
1416
1417 if (ret)
1418 break;
1419 }
1420
1421 return count;
1422}
1423
1424static ssize_t modem_reset_channels_4bit_dev_test_read(
1425 struct file *file,
1426 char __user *buffer,
1427 size_t count,
1428 loff_t *offset)
1429{
1430 memset((void *)buffer, 0, count);
1431
1432 snprintf(buffer, count,
1433 "\nMODEM_RESET_CHANNELS_4BIT_DEV_TEST\n"
1434 "==================================\n"
1435 "Description:\n"
1436 "TBD\n");
1437
1438 if (message_repeat == 1) {
1439 message_repeat = 0;
1440 return strnlen(buffer, count);
1441 } else {
1442 return 0;
1443 }
1444}
1445
1446const struct file_operations modem_reset_channels_4bit_dev_test_ops = {
1447 .open = sdio_al_test_open,
1448 .write = modem_reset_channels_4bit_dev_test_write,
1449 .read = modem_reset_channels_4bit_dev_test_read,
1450};
1451
1452/* MODEM RESET - CHANNELS IN 8BIT DEVICE TEST */
1453static ssize_t modem_reset_channels_8bit_dev_test_write(
1454 struct file *file,
1455 const char __user *buf,
1456 size_t count,
1457 loff_t *ppos)
1458{
1459 int ret = 0;
1460 int i = 0;
1461 int number = -1;
1462
1463 pr_info(TEST_MODULE_NAME "-- MODEM RESET - ALL CHANNELS IN "
1464 "8BIT DEVICE TEST --");
1465
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001466 number = sdio_al_test_extract_number(buf, count);
1467
1468 if (number < 0) {
1469 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1470 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001471 return count;
1472 }
1473
1474 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001475 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1476 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001477
1478 sdio_al_test_initial_dev_and_chan(test_ctx);
1479
1480 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]);
1481 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DUN]);
1482 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_CIQ]);
1483
1484 ret = test_start();
1485
1486 if (ret)
1487 break;
1488 }
1489
1490 return count;
1491}
1492
1493static ssize_t modem_reset_channels_8bit_dev_test_read(
1494 struct file *file,
1495 char __user *buffer,
1496 size_t count,
1497 loff_t *offset)
1498{
1499 memset((void *)buffer, 0, count);
1500
1501 snprintf(buffer, count,
1502 "\nMODEM_RESET_CHANNELS_8BIT_DEV_TEST\n"
1503 "==================================\n"
1504 "Description:\n"
1505 "TBD\n");
1506
1507 if (message_repeat == 1) {
1508 message_repeat = 0;
1509 return strnlen(buffer, count);
1510 } else {
1511 return 0;
1512 }
1513}
1514
1515const struct file_operations modem_reset_channels_8bit_dev_test_ops = {
1516 .open = sdio_al_test_open,
1517 .write = modem_reset_channels_8bit_dev_test_write,
1518 .read = modem_reset_channels_8bit_dev_test_read,
1519};
1520
1521/* MODEM RESET - ALL CHANNELS TEST */
1522static ssize_t modem_reset_all_channels_test_write(struct file *file,
1523 const char __user *buf,
1524 size_t count,
1525 loff_t *ppos)
1526{
1527 int ret = 0;
1528 int i = 0;
1529 int number = -1;
1530
1531 pr_info(TEST_MODULE_NAME "-- MODEM RESET - ALL CHANNELS TEST --");
1532
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001533 number = sdio_al_test_extract_number(buf, count);
1534
1535 if (number < 0) {
1536 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1537 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001538 return count;
1539 }
1540
1541 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001542 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1543 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001544
1545 sdio_al_test_initial_dev_and_chan(test_ctx);
1546
1547 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RPC]);
1548 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_QMI]);
1549 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DIAG]);
1550 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]);
1551 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DUN]);
1552 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_CIQ]);
1553
1554 ret = test_start();
1555
1556 if (ret)
1557 break;
1558 }
1559
1560 return count;
1561}
1562
1563static ssize_t modem_reset_all_channels_test_read(struct file *file,
1564 char __user *buffer,
1565 size_t count,
1566 loff_t *offset)
1567{
1568 memset((void *)buffer, 0, count);
1569
1570 snprintf(buffer, count,
1571 "\nMODEM_RESET_ALL_CHANNELS_TEST\n"
1572 "=============================\n"
1573 "Description:\n"
1574 "TBD\n");
1575
1576 if (message_repeat == 1) {
1577 message_repeat = 0;
1578 return strnlen(buffer, count);
1579 } else {
1580 return 0;
1581 }
1582}
1583
1584const struct file_operations modem_reset_all_channels_test_ops = {
1585 .open = sdio_al_test_open,
1586 .write = modem_reset_all_channels_test_write,
1587 .read = modem_reset_all_channels_test_read,
1588};
1589
Maya Erezefafaa82011-09-21 12:41:28 +03001590/* HOST SENDER WITH OPEN/CLOSE TEST */
1591static ssize_t open_close_test_write(struct file *file,
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001592 const char __user *buf,
1593 size_t count,
1594 loff_t *ppos)
1595{
1596 int ret = 0;
1597 struct test_channel **ch_arr = test_ctx->test_ch_arr;
1598 int i = 0;
1599 int number = -1;
1600
Maya Erezefafaa82011-09-21 12:41:28 +03001601 pr_info(TEST_MODULE_NAME "-- HOST SENDER WITH OPEN/CLOSE TEST --");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001602
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001603 number = sdio_al_test_extract_number(buf, count);
1604
1605 if (number < 0) {
1606 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1607 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001608 return count;
1609 }
1610
1611 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001612 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1613 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001614
1615 sdio_al_test_initial_dev_and_chan(test_ctx);
1616
1617 set_params_loopback_9k_close(ch_arr[SDIO_DIAG]);
1618 set_params_loopback_9k_close(ch_arr[SDIO_CIQ]);
Maya Erezefafaa82011-09-21 12:41:28 +03001619 set_params_loopback_9k_close(ch_arr[SDIO_RPC]);
1620 set_params_loopback_9k_close(ch_arr[SDIO_SMEM]);
1621 set_params_loopback_9k_close(ch_arr[SDIO_QMI]);
Maya Ereze05fc4d2011-09-11 14:18:43 +03001622 set_params_loopback_9k_close(ch_arr[SDIO_RMNT]);
Maya Erezefafaa82011-09-21 12:41:28 +03001623 set_params_loopback_9k_close(ch_arr[SDIO_DUN]);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001624
1625 ret = test_start();
1626
1627 if (ret)
1628 break;
1629
1630 pr_info(TEST_MODULE_NAME " -- correctness test for"
Maya Ereze05fc4d2011-09-11 14:18:43 +03001631 "DIAG, CIQ ");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001632 set_params_loopback_9k(ch_arr[SDIO_DIAG]);
1633 set_params_loopback_9k(ch_arr[SDIO_CIQ]);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001634
1635 ret = test_start();
1636
1637 if (ret)
1638 break;
1639 }
1640
1641 return count;
1642}
1643
Maya Erezefafaa82011-09-21 12:41:28 +03001644static ssize_t open_close_test_read(struct file *file,
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001645 char __user *buffer,
1646 size_t count,
1647 loff_t *offset)
1648{
1649 memset((void *)buffer, 0, count);
1650
1651 snprintf(buffer, count,
Maya Erezefafaa82011-09-21 12:41:28 +03001652 "\nOPEN_CLOSE_TEST\n"
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001653 "============================\n"
1654 "Description:\n"
Maya Ereze05fc4d2011-09-11 14:18:43 +03001655 "In this test the host sends 5k packets to the modem in the "
1656 "following sequence: Send a random burst of packets on "
1657 "Diag, CIQ and Rmnet channels, read 0 or a random number "
1658 "of packets, close and re-open the channel. At the end of the "
1659 "test, the channel is verified by running a loopback test\n");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001660
1661 if (message_repeat == 1) {
1662 message_repeat = 0;
1663 return strnlen(buffer, count);
1664 } else {
1665 return 0;
1666 }
1667}
1668
Maya Erezefafaa82011-09-21 12:41:28 +03001669const struct file_operations open_close_test_ops = {
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001670 .open = sdio_al_test_open,
Maya Erezefafaa82011-09-21 12:41:28 +03001671 .write = open_close_test_write,
1672 .read = open_close_test_read,
Maya Ereze05fc4d2011-09-11 14:18:43 +03001673};
1674
Maya Ereze05fc4d2011-09-11 14:18:43 +03001675/* HOST SENDER WITH OPEN/CLOSE FOR DUN & RMNET TEST */
1676static ssize_t open_close_dun_rmnet_test_write(struct file *file,
1677 const char __user *buf,
1678 size_t count,
1679 loff_t *ppos)
1680{
1681 int ret = 0;
1682 struct test_channel **ch_arr = test_ctx->test_ch_arr;
1683 int i = 0;
1684 int number = -1;
1685
1686 pr_info(TEST_MODULE_NAME "-- HOST SENDER WITH OPEN/CLOSE FOR "
1687 "DUN AND RMNET TEST --");
1688
1689 number = sdio_al_test_extract_number(buf, count);
1690
1691 if (number < 0) {
1692 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1693 "failed. number = %d\n", __func__, number);
1694 return count;
1695 }
1696
1697 for (i = 0 ; i < number ; ++i) {
1698 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1699 pr_info(TEST_MODULE_NAME " ===================");
1700
1701 sdio_al_test_initial_dev_and_chan(test_ctx);
1702
1703 set_params_loopback_9k_close(ch_arr[SDIO_DUN]);
1704 set_params_loopback_9k_close(ch_arr[SDIO_RMNT]);
1705
1706 ret = test_start();
1707
1708 if (ret)
1709 break;
1710 }
1711
1712 return count;
1713}
1714
1715static ssize_t open_close_dun_rmnet_test_read(struct file *file,
1716 char __user *buffer,
1717 size_t count,
1718 loff_t *offset)
1719{
1720 memset((void *)buffer, 0, count);
1721
1722 snprintf(buffer, count,
1723 "\nOPEN_CLOSE_DUN_RMNET_TEST\n"
1724 "============================\n"
1725 "Description:\n"
1726 "In this test the host sends 5k packets to the modem in the "
1727 "following sequence: Send a random burst of packets on "
1728 "DUN and Rmnet channels, read 0 or a random number "
1729 "of packets, close and re-open the channel.\n");
1730
1731 if (message_repeat == 1) {
1732 message_repeat = 0;
1733 return strnlen(buffer, count);
1734 } else {
1735 return 0;
1736 }
1737}
1738
1739const struct file_operations open_close_dun_rmnet_test_ops = {
1740 .open = sdio_al_test_open,
1741 .write = open_close_dun_rmnet_test_write,
1742 .read = open_close_dun_rmnet_test_read,
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001743};
1744
1745/* CLOSE CHANNEL & LPM TEST HOST WAKES THE CLIENT TEST */
1746static ssize_t close_chan_lpm_test_write(struct file *file,
1747 const char __user *buf,
1748 size_t count,
1749 loff_t *ppos)
1750{
1751 int ret = 0;
1752 int i = 0;
Yaniv Gardib4237782011-08-31 20:06:16 +03001753 int channel_num = 0;
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001754 int number = -1;
1755
1756 pr_info(TEST_MODULE_NAME "-- CLOSE CHANNEL & LPM TEST "
1757 "HOST WAKES THE CLIENT TEST --\n");
1758
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001759 number = sdio_al_test_extract_number(buf, count);
1760
1761 if (number < 0) {
1762 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1763 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001764 return count;
1765 }
1766
1767 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001768 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1769 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001770
1771 sdio_al_test_initial_dev_and_chan(test_ctx);
1772
Yaniv Gardib4237782011-08-31 20:06:16 +03001773 for (channel_num = 0 ; channel_num < SDIO_MAX_CHANNELS ;
1774 channel_num++) {
Yaniv Gardib4237782011-08-31 20:06:16 +03001775
1776 ret = close_channel_lpm_test(channel_num);
1777
1778 if (ret)
1779 break;
1780
1781 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
1782 SDIO_TEST_LPM_HOST_WAKER, 120);
1783
1784 ret = test_start();
1785
1786 if (ret)
1787 break;
1788 }
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001789
1790 if (ret) {
1791 pr_err(TEST_MODULE_NAME " -- Close channel & LPM Test "
1792 "FAILED: %d --\n", ret);
1793 } else {
1794 pr_err(TEST_MODULE_NAME " -- Close channel & LPM Test "
1795 "PASSED\n");
1796 }
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001797 }
1798
1799 return count;
1800}
1801
1802static ssize_t close_chan_lpm_test_read(struct file *file,
1803 char __user *buffer,
1804 size_t count,
1805 loff_t *offset)
1806{
1807 memset((void *)buffer, 0, count);
1808
1809 snprintf(buffer, count,
1810 "\nCLOSE_CHAN_LPM_TEST\n"
1811 "===================\n"
1812 "Description:\n"
1813 "TBD\n");
1814
1815 if (message_repeat == 1) {
1816 message_repeat = 0;
1817 return strnlen(buffer, count);
1818 } else {
1819 return 0;
1820 }
1821}
1822
1823const struct file_operations close_chan_lpm_test_ops = {
1824 .open = sdio_al_test_open,
1825 .write = close_chan_lpm_test_write,
1826 .read = close_chan_lpm_test_read,
1827};
1828
1829/* LPM TEST FOR DEVICE 1. CLIENT WAKES THE HOST TEST */
1830static ssize_t lpm_test_client_wakes_host_test_write(struct file *file,
1831 const char __user *buf,
1832 size_t count,
1833 loff_t *ppos)
1834{
1835 int ret = 0;
1836 int i = 0;
1837 int number = -1;
1838
1839 pr_info(TEST_MODULE_NAME "-- LPM TEST FOR DEVICE 1. CLIENT "
1840 "WAKES THE HOST TEST --\n");
1841
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001842 number = sdio_al_test_extract_number(buf, count);
1843
1844 if (number < 0) {
1845 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1846 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001847 return count;
1848 }
1849
1850 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001851 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1852 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001853
1854 sdio_al_test_initial_dev_and_chan(test_ctx);
1855
1856 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
1857 SDIO_TEST_LPM_CLIENT_WAKER, 90);
1858
1859 ret = test_start();
1860
1861 if (ret)
1862 break;
1863 }
1864
1865 return count;
1866}
1867
1868static ssize_t lpm_test_client_wakes_host_test_read(struct file *file,
1869 char __user *buffer,
1870 size_t count,
1871 loff_t *offset)
1872{
1873 memset((void *)buffer, 0, count);
1874
1875 snprintf(buffer, count,
1876 "\nLPM_TEST_CLIENT_WAKES_HOST_TEST\n"
1877 "===============================\n"
1878 "Description:\n"
1879 "In this test, the HOST is going into LPM mode,\n"
1880 "and the CLIENT is responsible to send it a message\n"
1881 "in order to wake it up\n\n"
1882 "END OF DESCRIPTION\n");
1883
1884 if (message_repeat == 1) {
1885 message_repeat = 0;
1886 return strnlen(buffer, count);
1887 } else {
1888 return 0;
1889 }
1890}
1891
1892const struct file_operations lpm_test_client_wakes_host_test_ops = {
1893 .open = sdio_al_test_open,
1894 .write = lpm_test_client_wakes_host_test_write,
1895 .read = lpm_test_client_wakes_host_test_read,
1896};
1897
1898/* LPM TEST FOR DEVICE 1. HOST WAKES THE CLIENT TEST */
1899static ssize_t lpm_test_host_wakes_client_test_write(struct file *file,
1900 const char __user *buf,
1901 size_t count,
1902 loff_t *ppos)
1903{
1904 int ret = 0;
1905 int i = 0;
1906 int number = -1;
1907
1908 pr_info(TEST_MODULE_NAME "-- LPM TEST FOR DEVICE 1. HOST "
1909 "WAKES THE CLIENT TEST --\n");
1910
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001911 number = sdio_al_test_extract_number(buf, count);
1912
1913 if (number < 0) {
1914 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1915 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001916 return count;
1917 }
1918
1919 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001920 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1921 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001922
1923 sdio_al_test_initial_dev_and_chan(test_ctx);
1924
1925 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
1926 SDIO_TEST_LPM_HOST_WAKER, 120);
1927
1928 ret = test_start();
1929
1930 if (ret)
1931 break;
1932 }
1933
1934 return count;
1935}
1936
1937static ssize_t lpm_test_host_wakes_client_test_read(struct file *file,
1938 char __user *buffer,
1939 size_t count,
1940 loff_t *offset)
1941{
1942 memset((void *)buffer, 0, count);
1943
1944 snprintf(buffer, count,
1945 "\nLPM_TEST_HOST_WAKES_CLIENT_TEST\n"
1946 "===============================\n"
1947 "Description:\n"
1948 "In this test, the CLIENT goes into LPM mode, and the\n"
1949 "HOST is responsible to send it a message\n"
1950 "in order to wake it up\n\n"
1951 "END OF DESCRIPTION\n");
1952
1953 if (message_repeat == 1) {
1954 message_repeat = 0;
1955 return strnlen(buffer, count);
1956 } else {
1957 return 0;
1958 }
1959}
1960
1961const struct file_operations lpm_test_host_wakes_client_test_ops = {
1962 .open = sdio_al_test_open,
1963 .write = lpm_test_host_wakes_client_test_write,
1964 .read = lpm_test_host_wakes_client_test_read,
1965};
1966
1967/* LPM TEST RANDOM, SINGLE CHANNEL TEST */
1968static ssize_t lpm_test_random_single_channel_test_write(
1969 struct file *file,
1970 const char __user *buf,
1971 size_t count,
1972 loff_t *ppos)
1973{
1974 int ret = 0;
1975 int i = 0;
1976 int number = -1;
1977
1978 pr_info(TEST_MODULE_NAME "-- LPM TEST RANDOM SINGLE "
1979 "CHANNEL TEST --\n");
1980
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001981 number = sdio_al_test_extract_number(buf, count);
1982
1983 if (number < 0) {
1984 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1985 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001986 return count;
1987 }
1988
1989 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001990 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1991 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001992
1993 sdio_al_test_initial_dev_and_chan(test_ctx);
1994
1995 set_pseudo_random_seed();
1996 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
1997 SDIO_TEST_LPM_RANDOM, 0);
1998
1999 ret = test_start();
2000
2001 if (ret)
2002 break;
2003 }
2004
2005 return count;
2006}
2007
2008static ssize_t lpm_test_random_single_channel_test_read(
2009 struct file *file,
2010 char __user *buffer,
2011 size_t count,
2012 loff_t *offset)
2013{
2014 memset((void *)buffer, 0, count);
2015
2016 snprintf(buffer, count,
2017 "\nLPM_TEST_RANDOM_SINGLE_CHANNEL_TEST\n"
2018 "===================================\n"
2019 "Description:\n"
2020 "In this test, the HOST and CLIENT "
2021 "send messages to each other,\n"
2022 "random in time, over RPC channel only.\n"
2023 "All events are being recorded, and later on,\n"
2024 "they are being analysed by the HOST and by the CLIENT\n,"
2025 "in order to check if the LPM mechanism worked properly,\n"
2026 "meaning:"
2027 " When all the relevant conditions are met, a device should:\n"
2028 "1. Go to sleep\n"
2029 "2. Wake up\n"
2030 "3. Stay awake\n\n"
2031 "END OF DESCRIPTION\n");
2032
2033 if (message_repeat == 1) {
2034 message_repeat = 0;
2035 return strnlen(buffer, count);
2036 } else {
2037 return 0;
2038 }
2039}
2040
2041const struct file_operations lpm_test_random_single_channel_test_ops = {
2042 .open = sdio_al_test_open,
2043 .write = lpm_test_random_single_channel_test_write,
2044 .read = lpm_test_random_single_channel_test_read,
2045};
2046
2047/* LPM TEST RANDOM, MULTI CHANNEL TEST */
2048static ssize_t lpm_test_random_multi_channel_test_write(
2049 struct file *file,
2050 const char __user *buf,
2051 size_t count,
2052 loff_t *ppos)
2053{
2054 int ret = 0;
2055 int i = 0;
2056 int number = -1;
2057
2058 pr_info(TEST_MODULE_NAME "-- LPM TEST RANDOM MULTI CHANNEL TEST --\n");
2059
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03002060 number = sdio_al_test_extract_number(buf, count);
2061
2062 if (number < 0) {
2063 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
2064 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002065 return count;
2066 }
2067
2068 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03002069 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
2070 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002071
2072 sdio_al_test_initial_dev_and_chan(test_ctx);
2073
2074 set_pseudo_random_seed();
2075
2076 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
2077 SDIO_TEST_LPM_RANDOM, 0);
2078 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_CIQ],
2079 SDIO_TEST_LPM_RANDOM, 0);
2080 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_DIAG],
2081 SDIO_TEST_LPM_RANDOM, 0);
2082 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_QMI],
2083 SDIO_TEST_LPM_RANDOM, 0);
2084
2085 ret = test_start();
2086
2087 if (ret)
2088 break;
2089 }
2090
2091 return count;
2092}
2093
2094static ssize_t lpm_test_random_multi_channel_test_read(
2095 struct file *file,
2096 char __user *buffer,
2097 size_t count,
2098 loff_t *offset)
2099{
2100 memset((void *)buffer, 0, count);
2101
2102 snprintf(buffer, count,
2103 "\nLPM_TEST_RANDOM_MULTI_CHANNEL_TEST\n"
2104 "==================================\n"
2105 "Description:\n"
2106 "In this test, the HOST and CLIENT "
2107 "send messages to each other,\n"
2108 "random in time, over RPC, QMI, DIAG AND CIQ channels\n"
2109 "(i.e, on both SDIO devices).\n"
2110 "All events are being recorded, and later on,\n"
2111 "they are being analysed by the HOST and by the CLIENT,\n"
2112 "in order to check if the LPM mechanism worked properly,\n"
2113 "meaning:"
2114 " When all the relevant conditions are met, a device should:\n"
2115 "1. Go to sleep\n"
2116 "2. Wake up\n"
2117 "3. Stay awake\n\n"
2118 "END OF DESCRIPTION\n");
2119
2120 if (message_repeat == 1) {
2121 message_repeat = 0;
2122 return strnlen(buffer, count);
2123 } else {
2124 return 0;
2125 }
2126}
2127
2128const struct file_operations lpm_test_random_multi_channel_test_ops = {
2129 .open = sdio_al_test_open,
2130 .write = lpm_test_random_multi_channel_test_write,
2131 .read = lpm_test_random_multi_channel_test_read,
2132};
2133
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002134static int sdio_al_test_debugfs_init(void)
2135{
2136 test_ctx->debug.debug_root = debugfs_create_dir("sdio_al_test",
2137 NULL);
2138 if (!test_ctx->debug.debug_root)
2139 return -ENOENT;
2140
2141 test_ctx->debug.debug_test_result = debugfs_create_u32(
2142 "test_result",
2143 S_IRUGO | S_IWUGO,
2144 test_ctx->debug.debug_root,
2145 &test_ctx->test_result);
2146
2147 test_ctx->debug.debug_dun_throughput = debugfs_create_u32(
2148 "dun_throughput",
2149 S_IRUGO | S_IWUGO,
2150 test_ctx->debug.debug_root,
2151 &test_ctx->debug.dun_throughput);
2152
2153 test_ctx->debug.debug_rmnt_throughput = debugfs_create_u32(
2154 "rmnt_throughput",
2155 S_IRUGO | S_IWUGO,
2156 test_ctx->debug.debug_root,
2157 &test_ctx->debug.rmnt_throughput);
2158
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002159 test_ctx->debug.rpc_sender_test =
2160 debugfs_create_file("10_rpc_sender_test",
2161 S_IRUGO | S_IWUGO,
2162 test_ctx->debug.debug_root,
2163 NULL,
2164 &rpc_sender_test_ops);
2165
2166 test_ctx->debug.rpc_qmi_diag_sender_test =
2167 debugfs_create_file("20_rpc_qmi_diag_sender_test",
2168 S_IRUGO | S_IWUGO,
2169 test_ctx->debug.debug_root,
2170 NULL,
2171 &rpc_qmi_diag_sender_test_ops);
2172
2173 test_ctx->debug.smem_test =
2174 debugfs_create_file("40_smem_test",
2175 S_IRUGO | S_IWUGO,
2176 test_ctx->debug.debug_root,
2177 NULL,
2178 &smem_test_ops);
2179
2180 test_ctx->debug.smem_rpc_test =
2181 debugfs_create_file("50_smem_rpc_test",
2182 S_IRUGO | S_IWUGO,
2183 test_ctx->debug.debug_root,
2184 NULL,
2185 &smem_rpc_test_ops);
2186
2187 test_ctx->debug.rmnet_a2_perf_test =
2188 debugfs_create_file("60_rmnet_a2_perf_test",
2189 S_IRUGO | S_IWUGO,
2190 test_ctx->debug.debug_root,
2191 NULL,
2192 &rmnet_a2_perf_test_ops);
2193
2194 test_ctx->debug.dun_a2_perf_test =
2195 debugfs_create_file("70_dun_a2_perf_test",
2196 S_IRUGO | S_IWUGO,
2197 test_ctx->debug.debug_root,
2198 NULL,
2199 &dun_a2_perf_test_ops);
2200
2201 test_ctx->debug.rmnet_dun_a2_perf_test =
2202 debugfs_create_file("80_rmnet_dun_a2_perf_test",
2203 S_IRUGO | S_IWUGO,
2204 test_ctx->debug.debug_root,
2205 NULL,
2206 &rmnet_dun_a2_perf_test_ops);
2207
2208 test_ctx->debug.rpc_sender_rmnet_a2_perf_test =
2209 debugfs_create_file("90_rpc_sender_rmnet_a2_perf_test",
2210 S_IRUGO | S_IWUGO,
2211 test_ctx->debug.debug_root,
2212 NULL,
2213 &rpc_sender_rmnet_a2_perf_test_ops);
2214
2215 test_ctx->debug.all_channels_test =
2216 debugfs_create_file("100_all_channels_test",
2217 S_IRUGO | S_IWUGO,
2218 test_ctx->debug.debug_root,
2219 NULL,
2220 &all_channels_test_ops);
2221
2222 test_ctx->debug.host_sender_no_lp_diag_test =
2223 debugfs_create_file("160_host_sender_no_lp_diag_test",
2224 S_IRUGO | S_IWUGO,
2225 test_ctx->debug.debug_root,
2226 NULL,
2227 &host_sender_no_lp_diag_test_ops);
2228
2229 test_ctx->debug.host_sender_no_lp_diag_rpc_ciq_test =
2230 debugfs_create_file("170_host_sender_no_lp_diag_rpc_ciq_test",
2231 S_IRUGO | S_IWUGO,
2232 test_ctx->debug.debug_root,
2233 NULL,
2234 &host_sender_no_lp_diag_rpc_ciq_test_ops);
2235
2236 test_ctx->debug.rmnet_small_packets_test =
2237 debugfs_create_file("180_rmnet_small_packets_test",
2238 S_IRUGO | S_IWUGO,
2239 test_ctx->debug.debug_root,
2240 NULL,
2241 &rmnet_small_packets_test_ops);
2242
2243 test_ctx->debug.rmnet_rtt_test =
2244 debugfs_create_file("190_rmnet_rtt_test",
2245 S_IRUGO | S_IWUGO,
2246 test_ctx->debug.debug_root,
2247 NULL,
2248 &rmnet_rtt_test_ops);
2249
2250 test_ctx->debug.modem_reset_rpc_test =
2251 debugfs_create_file("220_modem_reset_rpc_test",
2252 S_IRUGO | S_IWUGO,
2253 test_ctx->debug.debug_root,
2254 NULL,
2255 &modem_reset_rpc_test_ops);
2256
2257 test_ctx->debug.modem_reset_rmnet_test =
2258 debugfs_create_file("230_modem_reset_rmnet_test",
2259 S_IRUGO | S_IWUGO,
2260 test_ctx->debug.debug_root,
2261 NULL,
2262 &modem_reset_rmnet_test_ops);
2263
2264 test_ctx->debug.modem_reset_channels_4bit_dev_test =
2265 debugfs_create_file("240_modem_reset_channels_4bit_dev_test",
2266 S_IRUGO | S_IWUGO,
2267 test_ctx->debug.debug_root,
2268 NULL,
2269 &modem_reset_channels_4bit_dev_test_ops);
2270
2271 test_ctx->debug.modem_reset_channels_8bit_dev_test =
2272 debugfs_create_file("250_modem_reset_channels_8bit_dev_test",
2273 S_IRUGO | S_IWUGO,
2274 test_ctx->debug.debug_root,
2275 NULL,
2276 &modem_reset_channels_8bit_dev_test_ops);
2277
2278 test_ctx->debug.modem_reset_all_channels_test =
2279 debugfs_create_file("260_modem_reset_all_channels_test",
2280 S_IRUGO | S_IWUGO,
2281 test_ctx->debug.debug_root,
2282 NULL,
2283 &modem_reset_all_channels_test_ops);
2284
Maya Erezefafaa82011-09-21 12:41:28 +03002285 test_ctx->debug.open_close_test =
2286 debugfs_create_file("270_open_close_test",
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002287 S_IRUGO | S_IWUGO,
2288 test_ctx->debug.debug_root,
2289 NULL,
Maya Erezefafaa82011-09-21 12:41:28 +03002290 &open_close_test_ops);
Maya Ereze05fc4d2011-09-11 14:18:43 +03002291
2292 test_ctx->debug.open_close_dun_rmnet_test =
2293 debugfs_create_file("271_open_close_dun_rmnet_test",
2294 S_IRUGO | S_IWUGO,
2295 test_ctx->debug.debug_root,
2296 NULL,
2297 &open_close_dun_rmnet_test_ops);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002298
2299 test_ctx->debug.close_chan_lpm_test =
2300 debugfs_create_file("280_close_chan_lpm_test",
2301 S_IRUGO | S_IWUGO,
2302 test_ctx->debug.debug_root,
2303 NULL,
2304 &close_chan_lpm_test_ops);
2305
2306 test_ctx->debug.lpm_test_client_wakes_host_test =
2307 debugfs_create_file("600_lpm_test_client_wakes_host_test",
2308 S_IRUGO | S_IWUGO,
2309 test_ctx->debug.debug_root,
2310 NULL,
2311 &lpm_test_client_wakes_host_test_ops);
2312
2313 test_ctx->debug.lpm_test_host_wakes_client_test =
2314 debugfs_create_file("610_lpm_test_host_wakes_client_test",
2315 S_IRUGO | S_IWUGO,
2316 test_ctx->debug.debug_root,
2317 NULL,
2318 &lpm_test_host_wakes_client_test_ops);
2319
2320 test_ctx->debug.lpm_test_random_single_channel_test =
2321 debugfs_create_file("620_lpm_test_random_single_channel_test",
2322 S_IRUGO | S_IWUGO,
2323 test_ctx->debug.debug_root,
2324 NULL,
2325 &lpm_test_random_single_channel_test_ops);
2326
2327 test_ctx->debug.lpm_test_random_multi_channel_test =
2328 debugfs_create_file("630_lpm_test_random_multi_channel_test",
2329 S_IRUGO | S_IWUGO,
2330 test_ctx->debug.debug_root,
2331 NULL,
2332 &lpm_test_random_multi_channel_test_ops);
2333
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002334 if ((!test_ctx->debug.debug_dun_throughput) &&
2335 (!test_ctx->debug.debug_rmnt_throughput)) {
2336 debugfs_remove_recursive(test_ctx->debug.debug_root);
2337 test_ctx->debug.debug_root = NULL;
2338 return -ENOENT;
2339 }
2340 return 0;
2341}
2342
2343static void sdio_al_test_debugfs_cleanup(void)
2344{
2345 debugfs_remove(test_ctx->debug.debug_dun_throughput);
2346 debugfs_remove(test_ctx->debug.debug_rmnt_throughput);
2347 debugfs_remove(test_ctx->debug.debug_root);
2348}
2349#endif
2350
2351static int channel_name_to_id(char *name)
2352{
2353 pr_info(TEST_MODULE_NAME "%s: channel name %s\n",
2354 __func__, name);
2355
Maya Erez8afd564f2011-08-24 15:57:06 +03002356 if (!strncmp(name, "SDIO_RPC_TEST",
2357 strnlen("SDIO_RPC_TEST", CHANNEL_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002358 return SDIO_RPC;
Maya Erez8afd564f2011-08-24 15:57:06 +03002359 else if (!strncmp(name, "SDIO_QMI_TEST",
2360 strnlen("SDIO_QMI_TEST", TEST_CH_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002361 return SDIO_QMI;
Maya Erez8afd564f2011-08-24 15:57:06 +03002362 else if (!strncmp(name, "SDIO_RMNT_TEST",
2363 strnlen("SDIO_RMNT_TEST", TEST_CH_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002364 return SDIO_RMNT;
Maya Erez8afd564f2011-08-24 15:57:06 +03002365 else if (!strncmp(name, "SDIO_DIAG_TEST",
2366 strnlen("SDIO_DIAG", TEST_CH_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002367 return SDIO_DIAG;
Maya Erez8afd564f2011-08-24 15:57:06 +03002368 else if (!strncmp(name, "SDIO_DUN_TEST",
2369 strnlen("SDIO_DUN_TEST", TEST_CH_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002370 return SDIO_DUN;
Maya Erez8afd564f2011-08-24 15:57:06 +03002371 else if (!strncmp(name, "SDIO_SMEM_TEST",
2372 strnlen("SDIO_SMEM_TEST", TEST_CH_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002373 return SDIO_SMEM;
Maya Erez8afd564f2011-08-24 15:57:06 +03002374 else if (!strncmp(name, "SDIO_CIQ_TEST",
2375 strnlen("SDIO_CIQ_TEST", TEST_CH_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002376 return SDIO_CIQ;
2377 else
2378 return SDIO_MAX_CHANNELS;
2379
2380 return SDIO_MAX_CHANNELS;
2381}
2382
2383/**
Maya Erezefafaa82011-09-21 12:41:28 +03002384 * Allocate and add SDIO_SMEM platform device
2385 */
2386#ifdef CONFIG_MSM_SDIO_SMEM
2387static int add_sdio_smem(void)
2388{
2389 int ret = 0;
2390
2391 test_ctx->smem_pdev = platform_device_alloc("SDIO_SMEM", -1);
2392 ret = platform_device_add(test_ctx->smem_pdev);
2393 if (ret) {
2394 pr_err(TEST_MODULE_NAME ": platform_device_add failed, "
2395 "ret=%d\n", ret);
2396 return ret;
2397 }
2398 return 0;
2399}
2400#endif
2401
2402static int open_sdio_ch(struct test_channel *tch)
2403{
2404 int ret = 0;
2405
2406 if (!tch) {
2407 pr_err(TEST_MODULE_NAME ": %s NULL tch\n", __func__);
2408 return -EINVAL;
2409 }
2410
2411 if (!tch->ch_ready) {
2412 TEST_DBG(TEST_MODULE_NAME ":openning channel %s\n",
2413 tch->name);
2414 if (tch->ch_id == SDIO_SMEM) {
2415#ifdef CONFIG_MSM_SDIO_SMEM
2416 if (!test_ctx->smem_pdev)
2417 ret = add_sdio_smem();
2418 else
2419 ret = sdio_smem_open(test_ctx->sdio_smem);
2420 if (ret) {
2421 pr_err(TEST_MODULE_NAME
2422 ":openning channel %s failed\n",
2423 tch->name);
2424 tch->ch_ready = false;
2425 return -EINVAL;
2426 }
2427#endif
2428 } else {
2429 tch->ch_ready = true;
2430 ret = sdio_open(tch->name , &tch->ch, tch,
2431 notify);
2432 if (ret) {
2433 pr_err(TEST_MODULE_NAME
2434 ":openning channel %s failed\n",
2435 tch->name);
2436 tch->ch_ready = false;
2437 return -EINVAL;
2438 }
2439 }
2440 }
2441 return ret;
2442}
2443
2444static int close_sdio_ch(struct test_channel *tch)
2445{
2446 int ret = 0;
2447
2448 if (!tch) {
2449 pr_err(TEST_MODULE_NAME ": %s NULL tch\n", __func__);
2450 return -EINVAL;
2451 }
2452
2453 if (tch->ch_id == SDIO_SMEM) {
2454#ifdef CONFIG_MSM_SDIO_SMEM
2455 TEST_DBG(TEST_MODULE_NAME":%s closing channel %s",
2456 __func__, tch->name);
2457 ret = sdio_smem_unregister_client();
2458 test_ctx->smem_counter = 0;
2459#endif
2460 } else {
2461 ret = sdio_close(tch->ch);
2462 }
2463
2464 if (ret) {
2465 pr_err(TEST_MODULE_NAME":%s close channel %s"
2466 " failed\n", __func__, tch->name);
2467 } else {
2468 TEST_DBG(TEST_MODULE_NAME":%s close channel %s"
2469 " success\n", __func__, tch->name);
2470 tch->ch_ready = false;
2471 }
2472 return ret;
2473}
2474
2475/**
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002476 * Config message
2477 */
2478
2479static void send_config_msg(struct test_channel *test_ch)
2480{
2481 int ret = 0 ;
2482 u32 write_avail = 0;
2483 int size = sizeof(test_ch->config_msg);
2484
2485 pr_debug(TEST_MODULE_NAME "%s\n", __func__);
2486
2487 memcpy(test_ch->buf, (void *)&test_ch->config_msg, size);
2488
2489 if (test_ctx->exit_flag) {
2490 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
2491 return;
2492 }
2493
2494 pr_info(TEST_MODULE_NAME ":Sending the config message.\n");
2495
2496 /* wait for data ready event */
2497 write_avail = sdio_write_avail(test_ch->ch);
2498 pr_debug(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
2499 if (write_avail < size) {
2500 wait_event(test_ch->wait_q,
2501 atomic_read(&test_ch->tx_notify_count));
2502 atomic_dec(&test_ch->tx_notify_count);
2503 }
2504
2505 write_avail = sdio_write_avail(test_ch->ch);
2506 pr_debug(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
2507 if (write_avail < size) {
2508 pr_info(TEST_MODULE_NAME ":not enough write avail.\n");
2509 return;
2510 }
2511
2512 ret = sdio_write(test_ch->ch, test_ch->buf, size);
2513 if (ret)
2514 pr_err(TEST_MODULE_NAME ":%s sdio_write err=%d.\n",
2515 __func__, -ret);
2516 else
2517 pr_info(TEST_MODULE_NAME ":%s sent config_msg successfully.\n",
2518 __func__);
2519}
2520
2521/**
2522 * Loopback Test
2523 */
2524static void loopback_test(struct test_channel *test_ch)
2525{
2526 int ret = 0 ;
2527 u32 read_avail = 0;
2528 u32 write_avail = 0;
2529
2530 while (1) {
2531
2532 if (test_ctx->exit_flag) {
2533 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
2534 return;
2535 }
2536
2537 TEST_DBG(TEST_MODULE_NAME "--LOOPBACK WAIT FOR EVENT--.\n");
2538 /* wait for data ready event */
2539 wait_event(test_ch->wait_q,
2540 atomic_read(&test_ch->rx_notify_count));
2541 atomic_dec(&test_ch->rx_notify_count);
2542
2543 read_avail = sdio_read_avail(test_ch->ch);
2544 if (read_avail == 0)
2545 continue;
2546
2547
2548 write_avail = sdio_write_avail(test_ch->ch);
2549 if (write_avail < read_avail) {
2550 pr_info(TEST_MODULE_NAME
2551 ":not enough write avail.\n");
2552 continue;
2553 }
2554
2555 ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
2556 if (ret) {
2557 pr_info(TEST_MODULE_NAME
2558 ":worker, sdio_read err=%d.\n", -ret);
2559 continue;
2560 }
2561 test_ch->rx_bytes += read_avail;
2562
2563 TEST_DBG(TEST_MODULE_NAME ":worker total rx bytes = 0x%x.\n",
2564 test_ch->rx_bytes);
2565
2566
2567 ret = sdio_write(test_ch->ch,
2568 test_ch->buf, read_avail);
2569 if (ret) {
2570 pr_info(TEST_MODULE_NAME
2571 ":loopback sdio_write err=%d.\n",
2572 -ret);
2573 continue;
2574 }
2575 test_ch->tx_bytes += read_avail;
2576
2577 TEST_DBG(TEST_MODULE_NAME
2578 ":loopback total tx bytes = 0x%x.\n",
2579 test_ch->tx_bytes);
2580 } /* end of while */
2581}
2582
2583/**
2584 * Check if all tests completed
2585 */
2586static void check_test_completion(void)
2587{
2588 int i;
2589
2590 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
2591 struct test_channel *tch = test_ctx->test_ch_arr[i];
2592
2593 if ((!tch) || (!tch->is_used) || (!tch->ch_ready))
2594 continue;
2595 if (!tch->test_completed) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002596 pr_info(TEST_MODULE_NAME ": %s - Channel %s test is "
2597 "not completed", __func__, tch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002598 return;
2599 }
2600 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03002601 pr_info(TEST_MODULE_NAME ": %s - Test is completed", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002602 test_ctx->test_completed = 1;
2603 wake_up(&test_ctx->wait_q);
2604}
2605
2606static int pseudo_random_seed(unsigned int *seed_number)
2607{
2608 if (!seed_number)
2609 return 0;
2610
2611 *seed_number = (unsigned int)(((unsigned long)*seed_number *
2612 (unsigned long)1103515367) + 35757);
Maya Erezf204e692011-08-12 22:00:13 +03002613 return (int)((*seed_number / (64*1024)) % 500);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002614}
2615
Yaniv Gardi3e327762011-07-27 11:11:04 +03002616/* this function must be locked before accessing it */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002617static void lpm_test_update_entry(struct test_channel *tch,
2618 enum lpm_test_msg_type msg_type,
Yaniv Gardi3e327762011-07-27 11:11:04 +03002619 char *msg_name,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002620 int counter)
2621{
2622 u32 index = 0;
2623 static int print_full = 1;
Yaniv Gardi3e327762011-07-27 11:11:04 +03002624 struct sdio_test_device *test_device;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002625
2626 if (!tch) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002627 pr_err(TEST_MODULE_NAME ": %s - NULL test channel\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002628 return;
2629 }
2630
Yaniv Gardi3e327762011-07-27 11:11:04 +03002631 test_device = tch->test_device;
2632
2633 if (!test_device) {
2634 pr_err(TEST_MODULE_NAME ": %s - NULL test device\n", __func__);
2635 return;
2636 }
2637
Maya Erez8afd564f2011-08-24 15:57:06 +03002638 if (!test_device->lpm_arr) {
2639 pr_err(TEST_MODULE_NAME ": %s - NULL lpm_arr\n", __func__);
2640 return;
2641 }
2642
Yaniv Gardi3e327762011-07-27 11:11:04 +03002643 if (test_device->next_avail_entry_in_array >=
2644 test_device->array_size) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002645 pr_err(TEST_MODULE_NAME ": %s - lpm array is full",
2646 __func__);
Yaniv Gardi3e327762011-07-27 11:11:04 +03002647
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002648 if (print_full) {
2649 print_hex_dump(KERN_INFO, TEST_MODULE_NAME ": lpm_arr:",
2650 0, 32, 2,
Yaniv Gardi3e327762011-07-27 11:11:04 +03002651 (void *)test_device->lpm_arr,
2652 sizeof(test_device->lpm_arr), false);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002653 print_full = 0;
2654 }
2655 return;
2656 }
2657
Yaniv Gardi3e327762011-07-27 11:11:04 +03002658 index = test_device->next_avail_entry_in_array;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002659 if ((msg_type == LPM_MSG_SEND) || (msg_type == LPM_MSG_REC))
Yaniv Gardi3e327762011-07-27 11:11:04 +03002660 test_device->lpm_arr[index].counter = counter;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002661 else
Yaniv Gardi3e327762011-07-27 11:11:04 +03002662 test_device->lpm_arr[index].counter = 0;
2663
2664 test_device->lpm_arr[index].msg_type = msg_type;
2665 memcpy(test_device->lpm_arr[index].msg_name, msg_name,
2666 LPM_MSG_NAME_SIZE);
2667 test_device->lpm_arr[index].current_ms =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002668 jiffies_to_msecs(get_jiffies_64());
2669
Yaniv Gardi3e327762011-07-27 11:11:04 +03002670 test_device->lpm_arr[index].read_avail_mask =
2671 test_device->read_avail_mask;
2672
2673 if ((msg_type == LPM_SLEEP) || (msg_type == LPM_WAKEUP))
2674 memcpy(test_device->lpm_arr[index].chan_name, "DEVICE ",
2675 CHANNEL_NAME_SIZE);
2676 else
2677 memcpy(test_device->lpm_arr[index].chan_name, tch->name,
2678 CHANNEL_NAME_SIZE);
2679
2680 test_device->next_avail_entry_in_array++;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002681}
2682
2683static int wait_for_result_msg(struct test_channel *test_ch)
2684{
2685 u32 read_avail = 0;
2686 int ret = 0;
2687
Yaniv Gardi3e327762011-07-27 11:11:04 +03002688 pr_info(TEST_MODULE_NAME ": %s - START, channel %s\n",
2689 __func__, test_ch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002690
2691 while (1) {
2692 read_avail = sdio_read_avail(test_ch->ch);
2693
2694 if (read_avail == 0) {
2695 pr_info(TEST_MODULE_NAME
2696 ": read_avail is 0 for chan %s\n",
2697 test_ch->name);
2698 wait_event(test_ch->wait_q,
2699 atomic_read(&test_ch->rx_notify_count));
2700 atomic_dec(&test_ch->rx_notify_count);
2701 continue;
2702 }
2703
2704 memset(test_ch->buf, 0x00, test_ch->buf_size);
2705
2706 ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
2707 if (ret) {
2708 pr_info(TEST_MODULE_NAME ": sdio_read for chan"
2709 "%s failed, err=%d.\n",
2710 test_ch->name, -ret);
2711 goto exit_err;
2712 }
2713
2714 if (test_ch->buf[0] != TEST_CONFIG_SIGNATURE) {
2715 pr_info(TEST_MODULE_NAME ": Not a test_result "
2716 "signature. expected 0x%x. received 0x%x "
2717 "for chan %s\n",
2718 TEST_CONFIG_SIGNATURE,
2719 test_ch->buf[0],
2720 test_ch->name);
2721 continue;
2722 } else {
2723 pr_info(TEST_MODULE_NAME ": Signature is "
2724 "TEST_CONFIG_SIGNATURE as expected\n");
2725 break;
2726 }
2727 }
2728
2729 return test_ch->buf[1];
2730
2731exit_err:
2732 return 0;
2733}
2734
Yaniv Gardi3e327762011-07-27 11:11:04 +03002735static int check_random_lpm_test_array(struct sdio_test_device *test_dev)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002736{
2737 int i = 0, j = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002738 unsigned int delta_ms = 0;
2739 int arr_ind = 0;
Yaniv Gardi3e327762011-07-27 11:11:04 +03002740 int ret = 1;
2741 int notify_counter = 0;
2742 int sleep_counter = 0;
2743 int wakeup_counter = 0;
2744 int lpm_activity_counter = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002745
Yaniv Gardi3e327762011-07-27 11:11:04 +03002746 if (!test_dev) {
2747 pr_err(TEST_MODULE_NAME ": %s - NULL test device\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002748 return -ENODEV;
2749 }
2750
Yaniv Gardi3e327762011-07-27 11:11:04 +03002751 for (i = 0 ; i < test_dev->next_avail_entry_in_array ; ++i) {
2752 if (i == 0)
2753 pr_err(TEST_MODULE_NAME ": index %4d, chan=%2s, "
2754 "code=%1d=%4s, msg#%1d, ms from before=-1, "
2755 "read_mask=0x%d, ms=%2u",
2756 i,
2757 test_dev->lpm_arr[i].chan_name,
2758 test_dev->lpm_arr[i].msg_type,
2759 test_dev->lpm_arr[i].msg_name,
2760 test_dev->lpm_arr[i].counter,
2761 test_dev->lpm_arr[i].read_avail_mask,
2762 test_dev->lpm_arr[i].current_ms);
2763 else
2764 pr_err(TEST_MODULE_NAME ": index "
2765 "%4d, %2s, code=%1d=%4s, msg#%1d, ms from "
2766 "before=%2u, read_mask=0x%d, ms=%2u",
2767 i,
2768 test_dev->lpm_arr[i].chan_name,
2769 test_dev->lpm_arr[i].msg_type,
2770 test_dev->lpm_arr[i].msg_name,
2771 test_dev->lpm_arr[i].counter,
2772 test_dev->lpm_arr[i].current_ms -
2773 test_dev->lpm_arr[i-1].current_ms,
2774 test_dev->lpm_arr[i].read_avail_mask,
2775 test_dev->lpm_arr[i].current_ms);
2776 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002777
Yaniv Gardi3e327762011-07-27 11:11:04 +03002778 for (i = 0; i < test_dev->next_avail_entry_in_array; i++) {
2779 notify_counter = 0;
2780 sleep_counter = 0;
2781 wakeup_counter = 0;
2782
2783 if ((test_dev->lpm_arr[i].msg_type == LPM_MSG_SEND) ||
2784 (test_dev->lpm_arr[i].msg_type == LPM_MSG_REC)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002785 /* find the next message in the array */
Yaniv Gardi3e327762011-07-27 11:11:04 +03002786 arr_ind = test_dev->next_avail_entry_in_array;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002787 for (j = i+1; j < arr_ind; j++) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002788 if ((test_dev->lpm_arr[j].msg_type ==
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002789 LPM_MSG_SEND) ||
Yaniv Gardi3e327762011-07-27 11:11:04 +03002790 (test_dev->lpm_arr[j].msg_type ==
2791 LPM_MSG_REC) ||
2792 (test_dev->lpm_arr[j].msg_type ==
2793 LPM_NOTIFY))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002794 break;
Yaniv Gardi3e327762011-07-27 11:11:04 +03002795 if (test_dev->lpm_arr[j].msg_type ==
2796 LPM_SLEEP)
2797 sleep_counter++;
2798 if (test_dev->lpm_arr[j].msg_type ==
2799 LPM_WAKEUP)
2800 wakeup_counter++;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002801 }
2802 if (j == arr_ind) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002803 ret = 1;
2804 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002805 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03002806
2807 delta_ms = test_dev->lpm_arr[j].current_ms -
2808 test_dev->lpm_arr[i].current_ms;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002809 if (delta_ms < 30) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002810 if ((sleep_counter == 0)
2811 && (wakeup_counter == 0)) {
2812 continue;
2813 } else {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002814 pr_err(TEST_MODULE_NAME "%s: lpm "
2815 "activity while delta is less "
Yaniv Gardi3e327762011-07-27 11:11:04 +03002816 "than 30, i=%d, j=%d, "
2817 "sleep_counter=%d, "
2818 "wakeup_counter=%d",
2819 __func__, i, j,
2820 sleep_counter, wakeup_counter);
2821 ret = 0;
2822 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002823 }
2824 } else {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002825 if ((delta_ms > 90) &&
2826 (test_dev->lpm_arr[i].
2827 read_avail_mask == 0)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002828 if (j != i+3) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002829 pr_err(TEST_MODULE_NAME
2830 "%s: unexpected "
2831 "lpm activity "
2832 "while delta is "
2833 "bigger than "
2834 "90, i=%d, "
2835 "j=%d, "
2836 "notify_counter"
2837 "=%d",
2838 __func__, i, j,
2839 notify_counter);
2840 ret = 0;
2841 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002842 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03002843 lpm_activity_counter++;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002844 }
2845 }
2846 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002847 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03002848
2849 pr_info(TEST_MODULE_NAME ": %s - lpm_activity_counter=%d",
2850 __func__, lpm_activity_counter);
2851
2852 return ret;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002853}
2854
2855static int lpm_test_main_task(void *ptr)
2856{
2857 u32 read_avail = 0;
2858 int last_msg_index = 0;
2859 struct test_channel *test_ch = (struct test_channel *)ptr;
Yaniv Gardi3e327762011-07-27 11:11:04 +03002860 struct sdio_test_device *test_dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002861 struct lpm_msg lpm_msg;
2862 int ret = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002863 int host_result = 0;
2864
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002865 if (!test_ch) {
2866 pr_err(TEST_MODULE_NAME ": %s - NULL channel\n", __func__);
2867 return -ENODEV;
2868 }
2869
Yaniv Gardi3e327762011-07-27 11:11:04 +03002870 pr_err(TEST_MODULE_NAME ": %s - STARTED. channel %s\n",
2871 __func__, test_ch->name);
2872
2873 test_dev = test_ch->test_device;
2874
2875 if (!test_dev) {
2876 pr_err(TEST_MODULE_NAME ": %s - NULL Test Device\n", __func__);
2877 return -ENODEV;
2878 }
2879
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002880 while (last_msg_index < test_ch->config_msg.num_packets - 1) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002881
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002882 TEST_DBG(TEST_MODULE_NAME ": %s - "
2883 "IN LOOP last_msg_index=%d\n",
2884 __func__, last_msg_index);
2885
2886 read_avail = sdio_read_avail(test_ch->ch);
2887 if (read_avail == 0) {
2888 TEST_DBG(TEST_MODULE_NAME
2889 ":read_avail 0 for chan %s, "
2890 "wait for event\n",
2891 test_ch->name);
2892 wait_event(test_ch->wait_q,
2893 atomic_read(&test_ch->rx_notify_count));
2894 atomic_dec(&test_ch->rx_notify_count);
2895
2896 read_avail = sdio_read_avail(test_ch->ch);
2897 if (read_avail == 0) {
2898 pr_err(TEST_MODULE_NAME
2899 ":read_avail size %d for chan %s not as"
2900 " expected\n",
2901 read_avail, test_ch->name);
2902 continue;
2903 }
2904 }
2905
2906 memset(test_ch->buf, 0x00, sizeof(test_ch->buf));
2907
2908 ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
2909 if (ret) {
2910 pr_info(TEST_MODULE_NAME ":sdio_read for chan %s"
Yaniv Gardi3e327762011-07-27 11:11:04 +03002911 " err=%d.\n", test_ch->name, -ret);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002912 goto exit_err;
2913 }
2914
2915 memcpy((void *)&lpm_msg, test_ch->buf, sizeof(lpm_msg));
2916
Yaniv Gardi3e327762011-07-27 11:11:04 +03002917 /*
2918 * when reading from channel, we want to turn off the bit
2919 * mask that implies that there is pending data on that channel
2920 */
2921 if (test_ch->test_device != NULL) {
2922 spin_lock_irqsave(&test_dev->lpm_array_lock,
2923 test_dev->lpm_array_lock_flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002924
Yaniv Gardi3e327762011-07-27 11:11:04 +03002925 test_ch->notify_counter_per_chan--;
2926
2927 /*
2928 * if the channel has no pending data, turn off the
2929 * pending data bit mask of the channel
2930 */
2931 if (test_ch->notify_counter_per_chan == 0) {
2932 test_ch->test_device->read_avail_mask =
2933 test_ch->test_device->read_avail_mask &
2934 ~test_ch->channel_mask_id;
2935 }
2936
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002937 last_msg_index = lpm_msg.counter;
Yaniv Gardi3e327762011-07-27 11:11:04 +03002938 lpm_test_update_entry(test_ch,
2939 LPM_MSG_REC,
2940 "RECEIVE",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002941 last_msg_index);
Yaniv Gardi3e327762011-07-27 11:11:04 +03002942
2943 spin_unlock_irqrestore(&test_dev->lpm_array_lock,
2944 test_dev->lpm_array_lock_flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002945 }
2946 }
2947
Yaniv Gardi3e327762011-07-27 11:11:04 +03002948 pr_info(TEST_MODULE_NAME ":%s: Finished to recieve all (%d) "
2949 "packets from the modem %s. Waiting for result_msg",
2950 __func__, test_ch->config_msg.num_packets, test_ch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002951
2952 /* Wait for the resault message from the modem */
Yaniv Gardi3e327762011-07-27 11:11:04 +03002953 test_ch->modem_result_per_chan = wait_for_result_msg(test_ch);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002954
Yaniv Gardi3e327762011-07-27 11:11:04 +03002955 /*
2956 * the DEVICE modem result is a failure if one of the channels on
2957 * that device, got modem_result = 0. this is why we bitwise "AND" each
2958 * time another channel completes its task
2959 */
2960 test_dev->modem_result_per_dev &= test_ch->modem_result_per_chan;
2961
2962 /*
2963 * when reading from channel, we want to turn off the bit
2964 * mask that implies that there is pending data on that channel
2965 */
2966 spin_lock_irqsave(&test_dev->lpm_array_lock,
2967 test_dev->lpm_array_lock_flags);
2968
2969 test_dev->open_channels_counter_to_recv--;
2970
2971 /* turning off the read_avail bit of the channel */
2972 test_ch->test_device->read_avail_mask =
2973 test_ch->test_device->read_avail_mask &
2974 ~test_ch->channel_mask_id;
2975
2976 spin_unlock_irqrestore(&test_dev->lpm_array_lock,
2977 test_dev->lpm_array_lock_flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002978
2979 /* Wait for all the packets to be sent to the modem */
2980 while (1) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002981 spin_lock_irqsave(&test_dev->lpm_array_lock,
2982 test_dev->lpm_array_lock_flags);
2983
2984 if (test_ch->next_index_in_sent_msg_per_chan >=
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002985 test_ch->config_msg.num_packets - 1) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002986
2987 spin_unlock_irqrestore(&test_dev->lpm_array_lock,
2988 test_dev->lpm_array_lock_flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002989 break;
2990 } else {
2991 pr_info(TEST_MODULE_NAME ":%s: Didn't finished to send "
Yaniv Gardi3e327762011-07-27 11:11:04 +03002992 "all packets, "
2993 "next_index_in_sent_msg_per_chan = %d ",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002994 __func__,
Yaniv Gardi3e327762011-07-27 11:11:04 +03002995 test_ch->next_index_in_sent_msg_per_chan);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002996 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03002997 spin_unlock_irqrestore(&test_dev->lpm_array_lock,
2998 test_dev->lpm_array_lock_flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002999 msleep(60);
3000 }
3001
Yaniv Gardi3e327762011-07-27 11:11:04 +03003002 if (test_dev->open_channels_counter_to_recv != 0 ||
3003 test_dev->open_channels_counter_to_send != 0) {
3004 test_ch->test_completed = 1;
3005 test_ch->next_index_in_sent_msg_per_chan = 0;
3006 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003007 } else {
Yaniv Gardi3e327762011-07-27 11:11:04 +03003008 test_ctx->number_of_active_devices--;
3009 sdio_al_unregister_lpm_cb(test_ch->sdio_al_device);
3010
3011 if (test_ch->test_type == SDIO_TEST_LPM_RANDOM)
3012 host_result = check_random_lpm_test_array(test_dev);
3013
3014 pr_info(TEST_MODULE_NAME ": %s - host_result=%d. "
3015 "device_modem_result=%d",
3016 __func__, host_result, test_dev->modem_result_per_dev);
3017
3018 test_ch->test_completed = 1;
3019 if (test_dev->modem_result_per_dev && host_result) {
3020 pr_info(TEST_MODULE_NAME ": %s - Random LPM "
3021 "TEST_PASSED for device %d of %d\n",
3022 __func__,
3023 (test_ctx->max_number_of_devices-
3024 test_ctx->number_of_active_devices),
3025 test_ctx->max_number_of_devices);
3026 test_dev->final_result_per_dev = 1; /* PASSED */
3027 } else {
3028 pr_info(TEST_MODULE_NAME ": %s - Random LPM "
3029 "TEST_FAILED for device %d of %d\n",
3030 __func__,
3031 (test_ctx->max_number_of_devices-
3032 test_ctx->number_of_active_devices),
3033 test_ctx->max_number_of_devices);
3034 test_dev->final_result_per_dev = 0; /* FAILED */
3035 }
3036
3037 test_dev->next_avail_entry_in_array = 0;
3038 test_ch->next_index_in_sent_msg_per_chan = 0;
3039
3040 check_test_completion();
3041
3042 kfree(test_ch->test_device->lpm_arr);
3043
3044 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003045 }
3046
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003047exit_err:
3048 pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
3049 test_ch->name);
3050 test_ch->test_completed = 1;
Yaniv Gardi3e327762011-07-27 11:11:04 +03003051 test_dev->open_channels_counter_to_recv--;
3052 test_dev->next_avail_entry_in_array = 0;
3053 test_ch->next_index_in_sent_msg_per_chan = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003054 test_ch->test_result = TEST_FAILED;
3055 check_test_completion();
3056 return -ENODEV;
3057}
3058
3059static int lpm_test_create_read_thread(struct test_channel *test_ch)
3060{
Yaniv Gardi3e327762011-07-27 11:11:04 +03003061 struct sdio_test_device *test_dev;
3062
3063 pr_info(TEST_MODULE_NAME ": %s - STARTED channel %s\n",
3064 __func__, test_ch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003065
3066 if (!test_ch) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03003067 pr_err(TEST_MODULE_NAME ": %s - NULL test channel\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003068 return -ENODEV;
3069 }
3070
Yaniv Gardi3e327762011-07-27 11:11:04 +03003071 test_dev = test_ch->test_device;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003072
Yaniv Gardi3e327762011-07-27 11:11:04 +03003073 if (!test_dev) {
3074 pr_err(TEST_MODULE_NAME ": %s - NULL test device\n", __func__);
3075 return -ENODEV;
3076 }
3077
3078 test_dev->lpm_test_task.task_name = SDIO_LPM_TEST;
3079
3080 test_dev->lpm_test_task.lpm_task =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003081 kthread_create(lpm_test_main_task,
3082 (void *)(test_ch),
Yaniv Gardi3e327762011-07-27 11:11:04 +03003083 test_dev->lpm_test_task.task_name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003084
Yaniv Gardi3e327762011-07-27 11:11:04 +03003085 if (IS_ERR(test_dev->lpm_test_task.lpm_task)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003086 pr_err(TEST_MODULE_NAME ": %s - kthread_create() failed\n",
3087 __func__);
3088 return -ENOMEM;
3089 }
3090
Yaniv Gardi3e327762011-07-27 11:11:04 +03003091 wake_up_process(test_dev->lpm_test_task.lpm_task);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003092
3093 return 0;
3094}
3095
3096static void lpm_continuous_rand_test(struct test_channel *test_ch)
3097{
3098 unsigned int local_ms = 0;
3099 int ret = 0;
3100 unsigned int write_avail = 0;
Yaniv Gardi3e327762011-07-27 11:11:04 +03003101 struct sdio_test_device *test_dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003102
3103 pr_info(MODULE_NAME ": %s - STARTED\n", __func__);
3104
3105 if (!test_ch) {
3106 pr_err(TEST_MODULE_NAME ": %s - NULL channel\n", __func__);
3107 return;
3108 }
3109
Yaniv Gardi3e327762011-07-27 11:11:04 +03003110 test_dev = test_ch->test_device;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003111
Yaniv Gardi3e327762011-07-27 11:11:04 +03003112 if (!test_dev) {
3113 pr_err(TEST_MODULE_NAME ": %s - NULL Test Device\n", __func__);
3114 return;
3115 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003116
3117 ret = lpm_test_create_read_thread(test_ch);
3118 if (ret != 0) {
3119 pr_err(TEST_MODULE_NAME ": %s - failed to create lpm reading "
3120 "thread", __func__);
3121 }
3122
Yaniv Gardi3e327762011-07-27 11:11:04 +03003123 while (test_ch->next_index_in_sent_msg_per_chan <=
3124 test_ch->config_msg.num_packets - 1) {
3125
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003126 struct lpm_msg msg;
3127 u32 ret = 0;
3128
Yaniv Gardi3e327762011-07-27 11:11:04 +03003129 /* sleeping period is dependent on number of open channels */
Maya Erezf204e692011-08-12 22:00:13 +03003130 test_ch->config_msg.test_param =
3131 test_ctx->lpm_pseudo_random_seed;
Yaniv Gardi3e327762011-07-27 11:11:04 +03003132
3133 local_ms = test_dev->open_channels_counter_to_send *
Maya Erezf204e692011-08-12 22:00:13 +03003134 test_ctx->lpm_pseudo_random_seed;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003135 TEST_DBG(TEST_MODULE_NAME ":%s: SLEEPING for %d ms",
3136 __func__, local_ms);
3137 msleep(local_ms);
3138
Yaniv Gardi3e327762011-07-27 11:11:04 +03003139 msg.counter = test_ch->next_index_in_sent_msg_per_chan;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003140 msg.signature = LPM_TEST_CONFIG_SIGNATURE;
3141 msg.reserve1 = 0;
3142 msg.reserve2 = 0;
3143
3144 /* wait for data ready event */
3145 write_avail = sdio_write_avail(test_ch->ch);
3146 pr_debug(TEST_MODULE_NAME ": %s: write_avail=%d\n",
3147 __func__, write_avail);
3148 if (write_avail < sizeof(msg)) {
3149 wait_event(test_ch->wait_q,
3150 atomic_read(&test_ch->tx_notify_count));
3151 atomic_dec(&test_ch->tx_notify_count);
3152 }
3153
3154 write_avail = sdio_write_avail(test_ch->ch);
3155 if (write_avail < sizeof(msg)) {
3156 pr_info(TEST_MODULE_NAME ": %s: not enough write "
3157 "avail.\n", __func__);
3158 break;
3159 }
3160
3161 ret = sdio_write(test_ch->ch, (u32 *)&msg, sizeof(msg));
3162 if (ret)
3163 pr_err(TEST_MODULE_NAME ":%s: sdio_write err=%d.\n",
3164 __func__, -ret);
3165
Yaniv Gardi3e327762011-07-27 11:11:04 +03003166 TEST_DBG(TEST_MODULE_NAME ": %s: for chan %s, write, "
3167 "msg # %d\n",
3168 __func__,
3169 test_ch->name,
3170 test_ch->next_index_in_sent_msg_per_chan);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003171
Yaniv Gardi3e327762011-07-27 11:11:04 +03003172 if (test_ch->test_type == SDIO_TEST_LPM_RANDOM) {
3173 spin_lock_irqsave(&test_dev->lpm_array_lock,
3174 test_dev->lpm_array_lock_flags);
3175 lpm_test_update_entry(test_ch, LPM_MSG_SEND,
3176 "SEND ",
3177 test_ch->
3178 next_index_in_sent_msg_per_chan);
3179
3180 test_ch->next_index_in_sent_msg_per_chan++;
3181
3182 spin_unlock_irqrestore(&test_dev->lpm_array_lock,
3183 test_dev->lpm_array_lock_flags);
3184 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003185 }
3186
Yaniv Gardi3e327762011-07-27 11:11:04 +03003187 spin_lock_irqsave(&test_dev->lpm_array_lock,
3188 test_dev->lpm_array_lock_flags);
3189 test_dev->open_channels_counter_to_send--;
3190 spin_unlock_irqrestore(&test_dev->lpm_array_lock,
3191 test_dev->lpm_array_lock_flags);
3192
3193 pr_info(TEST_MODULE_NAME ": %s: - Finished to send all (%d) "
3194 "packets to the modem on channel %s",
3195 __func__, test_ch->config_msg.num_packets, test_ch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003196
3197 return;
3198}
3199
3200static void lpm_test(struct test_channel *test_ch)
3201{
Yaniv Gardi3e327762011-07-27 11:11:04 +03003202 pr_info(TEST_MODULE_NAME ": %s - START channel %s\n", __func__,
3203 test_ch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003204
3205 if (!test_ch) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03003206 pr_err(TEST_MODULE_NAME ": %s - NULL test channel\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003207 return;
3208 }
3209
Yaniv Gardi3e327762011-07-27 11:11:04 +03003210 test_ch->modem_result_per_chan = wait_for_result_msg(test_ch);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003211 pr_debug(TEST_MODULE_NAME ": %s - delete the timeout timer\n",
3212 __func__);
3213 del_timer_sync(&test_ch->timeout_timer);
3214
Yaniv Gardi3e327762011-07-27 11:11:04 +03003215 if (test_ch->modem_result_per_chan == 0) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003216 pr_err(TEST_MODULE_NAME ": LPM TEST - Client didn't sleep. "
3217 "Result Msg - is_successful=%d\n", test_ch->buf[1]);
3218 goto exit_err;
3219 } else {
3220 pr_info(TEST_MODULE_NAME ": %s -"
3221 "LPM 9K WAS SLEEPING - PASS\n", __func__);
3222 if (test_ch->test_result == TEST_PASSED) {
3223 pr_info(TEST_MODULE_NAME ": LPM TEST_PASSED\n");
3224 test_ch->test_completed = 1;
3225 check_test_completion();
3226 } else {
3227 pr_err(TEST_MODULE_NAME ": LPM TEST - Host didn't "
3228 "sleep. Client slept\n");
3229 goto exit_err;
3230 }
3231 }
3232
3233 return;
3234
3235exit_err:
3236 pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
3237 test_ch->name);
3238 test_ch->test_completed = 1;
3239 test_ch->test_result = TEST_FAILED;
3240 check_test_completion();
3241 return;
3242}
3243
3244
3245/**
3246 * LPM Test while the host wakes up the modem
3247 */
3248static void lpm_test_host_waker(struct test_channel *test_ch)
3249{
3250 pr_info(TEST_MODULE_NAME ": %s - START\n", __func__);
3251 wait_event(test_ch->wait_q, atomic_read(&test_ch->wakeup_client));
3252 atomic_set(&test_ch->wakeup_client, 0);
3253
3254 pr_info(TEST_MODULE_NAME ": %s - Sending the config_msg to wakeup "
3255 " the client\n", __func__);
3256 send_config_msg(test_ch);
3257
3258 lpm_test(test_ch);
3259}
3260
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003261/**
3262 * Writes number of packets into test channel
3263 * @test_ch: test channel control struct
3264 * @burst_size: number of packets to send
3265 */
3266static int write_packet_burst(struct test_channel *test_ch,
3267 int burst_size)
3268{
3269 int ret = 0;
3270 int packet_count = 0;
3271 unsigned int random_num = 0;
3272 int size = test_ch->packet_length; /* first packet size */
3273 u32 write_avail = 0;
3274
3275 while (packet_count < burst_size) {
3276 /* wait for data ready event */
3277 write_avail = sdio_write_avail(test_ch->ch);
3278 TEST_DBG(TEST_MODULE_NAME ":%s write_avail=%d,size=%d on chan"
3279 " %s\n", __func__,
3280 write_avail, size, test_ch->name);
3281 if (write_avail < size) {
3282 TEST_DBG(TEST_MODULE_NAME ":%s wait for event on"
3283 " chan %s\n", __func__, test_ch->name);
3284 wait_event(test_ch->wait_q,
3285 atomic_read(&test_ch->tx_notify_count));
3286 atomic_dec(&test_ch->tx_notify_count);
3287 }
3288 write_avail = sdio_write_avail(test_ch->ch);
3289 if (write_avail < size) {
3290 pr_info(TEST_MODULE_NAME ":%s not enough write"
3291 " avail %d, need %d on chan %s\n",
3292 __func__, write_avail, size,
3293 test_ch->name);
3294 continue;
3295 }
3296 ret = sdio_write(test_ch->ch, test_ch->buf, size);
3297 if (ret) {
3298 pr_err(TEST_MODULE_NAME ":%s sdio_write "
3299 "failed (%d) on chan %s\n", __func__,
3300 ret, test_ch->name);
3301 break;
3302 }
3303 udelay(1000); /*low bus usage while running number of channels*/
3304 TEST_DBG(TEST_MODULE_NAME ":%s() successfully write %d bytes"
3305 ", packet_count=%d on chan %s\n", __func__,
3306 size, packet_count, test_ch->name);
3307 test_ch->tx_bytes += size;
3308 packet_count++;
3309 /* get next packet size */
3310 random_num = get_random_int();
3311 size = (random_num % test_ch->packet_length) + 1;
3312 }
3313 return ret;
3314}
Maya Ereze05fc4d2011-09-11 14:18:43 +03003315
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003316/**
3317 * Reads packet from test channel and checks that packet number
3318 * encoded into the packet is equal to packet_counter
Maya Ereze05fc4d2011-09-11 14:18:43 +03003319 * This function is applicable for packet mode channels only
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003320 *
3321 * @test_ch: test channel
3322 * @size: expected packet size
3323 * @packet_counter: number to validate readed packet
3324 */
Maya Ereze05fc4d2011-09-11 14:18:43 +03003325static int read_data_from_packet_ch(struct test_channel *test_ch,
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003326 unsigned int size,
3327 int packet_counter)
3328{
3329 u32 read_avail = 0;
3330 int ret = 0;
3331
Maya Ereze05fc4d2011-09-11 14:18:43 +03003332 if (!test_ch || !test_ch->ch) {
3333 pr_err(TEST_MODULE_NAME
3334 ":%s: NULL channel\n", __func__);
3335 return -EINVAL;
3336 }
3337
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003338 if (!test_ch->ch->is_packet_mode) {
3339 pr_err(TEST_MODULE_NAME
3340 ":%s:not packet mode ch %s\n",
3341 __func__, test_ch->name);
3342 return -EINVAL;
3343 }
3344 read_avail = sdio_read_avail(test_ch->ch);
3345 /* wait for read data ready event */
3346 if (read_avail < size) {
3347 TEST_DBG(TEST_MODULE_NAME ":%s() wait for rx data on "
3348 "chan %s\n", __func__, test_ch->name);
3349 wait_event(test_ch->wait_q,
3350 atomic_read(&test_ch->rx_notify_count));
3351 atomic_dec(&test_ch->rx_notify_count);
3352 }
3353 read_avail = sdio_read_avail(test_ch->ch);
3354 TEST_DBG(TEST_MODULE_NAME ":%s read_avail=%d bytes on chan %s\n",
3355 __func__, read_avail, test_ch->name);
3356
3357 if (read_avail != size) {
3358 pr_err(TEST_MODULE_NAME
3359 ":read_avail size %d for chan %s not as "
3360 "expected size %d\n",
3361 read_avail, test_ch->name, size);
3362 return -EINVAL;
3363 }
3364
3365 ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
3366 if (ret) {
3367 pr_err(TEST_MODULE_NAME ":%s() sdio_read for chan %s (%d)\n",
3368 __func__, test_ch->name, -ret);
3369 return ret;
3370 }
3371 if ((test_ch->buf[0] != packet_counter) && (size != 1)) {
3372 pr_err(TEST_MODULE_NAME ":Read WRONG DATA"
3373 " for chan %s, size=%d\n",
3374 test_ch->name, size);
3375 return -EINVAL;
3376 }
3377 return 0;
3378}
3379
Maya Ereze05fc4d2011-09-11 14:18:43 +03003380
3381/**
3382 * Reads packet from test channel and checks that packet number
3383 * encoded into the packet is equal to packet_counter
3384 * This function is applicable for streaming mode channels only
3385 *
3386 * @test_ch: test channel
3387 * @size: expected packet size
3388 * @packet_counter: number to validate readed packet
3389 */
3390static int read_data_from_stream_ch(struct test_channel *test_ch,
3391 unsigned int size,
3392 int packet_counter)
3393{
3394 u32 read_avail = 0;
3395 int ret = 0;
3396
3397 if (!test_ch || !test_ch->ch) {
3398 pr_err(TEST_MODULE_NAME
3399 ":%s: NULL channel\n", __func__);
3400 return -EINVAL;
3401 }
3402
3403 if (test_ch->ch->is_packet_mode) {
3404 pr_err(TEST_MODULE_NAME
3405 ":%s:not streaming mode ch %s\n",
3406 __func__, test_ch->name);
3407 return -EINVAL;
3408 }
3409 read_avail = sdio_read_avail(test_ch->ch);
3410 /* wait for read data ready event */
3411 if (read_avail < size) {
3412 TEST_DBG(TEST_MODULE_NAME ":%s() wait for rx data on "
3413 "chan %s\n", __func__, test_ch->name);
3414 wait_event(test_ch->wait_q,
3415 atomic_read(&test_ch->rx_notify_count));
3416 atomic_dec(&test_ch->rx_notify_count);
3417 }
3418 read_avail = sdio_read_avail(test_ch->ch);
3419 TEST_DBG(TEST_MODULE_NAME ":%s read_avail=%d bytes on chan %s\n",
3420 __func__, read_avail, test_ch->name);
3421
3422 if (read_avail < size) {
3423 pr_err(TEST_MODULE_NAME
3424 ":read_avail size %d for chan %s not as "
3425 "expected size %d\n",
3426 read_avail, test_ch->name, size);
3427 return -EINVAL;
3428 }
3429
3430 ret = sdio_read(test_ch->ch, test_ch->buf, size + A2_HEADER_OVERHEAD);
3431 if (ret) {
3432 pr_err(TEST_MODULE_NAME ":%s() sdio_read for chan %s (%d)\n",
3433 __func__, test_ch->name, -ret);
3434 return ret;
3435 }
3436 if ((test_ch->buf[A2_HEADER_OVERHEAD/4] != packet_counter) &&
3437 (size != 1)) {
3438 pr_err(TEST_MODULE_NAME ":Read WRONG DATA"
3439 " for chan %s, size=%d, packet_counter=%d\n",
3440 test_ch->name, size, packet_counter);
3441 print_hex_dump(KERN_INFO, TEST_MODULE_NAME ": rmnet:",
3442 0, 32, 2,
3443 (void *)test_ch->buf,
3444 size + A2_HEADER_OVERHEAD, false);
3445 return -EINVAL;
3446 }
3447 return 0;
3448}
3449
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003450/**
Maya Erezefafaa82011-09-21 12:41:28 +03003451 * Test close channel feature for SDIO_SMEM channel:
3452 * close && re-open the SDIO_SMEM channel.
3453 */
3454#ifdef CONFIG_MSM_SDIO_SMEM
3455static void open_close_smem_test(struct test_channel *test_ch)
3456{
3457 int i = 0;
3458 int ret = 0;
3459
3460 pr_info(TEST_MODULE_NAME ":%s\n", __func__);
3461
3462 for (i = 0; i < 100 ; ++i) {
3463 ret = close_sdio_ch(test_ch);
3464 if (ret) {
3465 pr_err(TEST_MODULE_NAME ":%s close_sdio_ch for ch %s"
3466 " failed\n",
3467 __func__, test_ch->name);
3468 goto exit_err;
3469 }
3470 ret = open_sdio_ch(test_ch);
3471 if (ret) {
3472 pr_err(TEST_MODULE_NAME ":%s open_sdio_ch for ch %s "
3473 " failed\n",
3474 __func__, test_ch->name);
3475 goto exit_err;
3476 }
3477 }
3478
3479 pr_info(TEST_MODULE_NAME ":%s TEST PASS for chan %s.\n", __func__,
3480 test_ch->name);
3481 test_ch->test_completed = 1;
3482 test_ch->test_result = TEST_PASSED;
3483 check_test_completion();
3484 return;
3485exit_err:
3486 pr_info(TEST_MODULE_NAME ":%s TEST FAIL for chan %s.\n", __func__,
3487 test_ch->name);
3488 test_ch->test_completed = 1;
3489 test_ch->test_result = TEST_FAILED;
3490 check_test_completion();
3491 return;
3492}
3493#endif
3494
3495/**
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003496 * Test close channel feature:
3497 * 1. write random packet number into channel
3498 * 2. read some data from channel (do this only for second half of
3499 * requested packets to send).
3500 * 3. close && re-open then repeat 1.
3501 *
3502 * Total packets to send: test_ch->config_msg.num_packets.
3503 * Burst size is random in [1..test_ch->max_burst_size] range
3504 * Packet size is random in [1..test_ch->packet_length]
3505 */
3506static void open_close_test(struct test_channel *test_ch)
3507{
3508 int ret = 0;
3509 u32 read_avail = 0;
3510 int total_packet_count = 0;
Maya Ereze05fc4d2011-09-11 14:18:43 +03003511 int size = 0;
3512 u16 *buf16 = NULL;
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003513 int i;
3514 int max_packet_count = 0;
3515 unsigned int random_num = 0;
Maya Ereze05fc4d2011-09-11 14:18:43 +03003516 int curr_burst_size = 0;
3517
3518 if (!test_ch || !test_ch->ch) {
3519 pr_err(TEST_MODULE_NAME ":%s NULL channel\n",
3520 __func__);
3521 return;
3522 }
3523
3524 curr_burst_size = test_ch->max_burst_size;
3525 size = test_ch->packet_length;
3526 buf16 = (u16 *) test_ch->buf;
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003527
3528 /* the test sends configured number of packets in
3529 2 portions: first without reading between write bursts,
3530 second with it */
3531 max_packet_count = test_ch->config_msg.num_packets / 2;
3532
3533 pr_info(TEST_MODULE_NAME ":%s channel %s, total packets:%d,"
3534 " max packet size %d, max burst size:%d\n",
3535 __func__, test_ch->name,
3536 test_ch->config_msg.num_packets, test_ch->packet_length,
3537 test_ch->max_burst_size);
3538 for (i = 0 ; i < size / 2 ; i++)
3539 buf16[i] = (u16) (i & 0xFFFF);
3540
3541 for (i = 0; i < 2 ; i++) {
3542 total_packet_count = 0;
3543 while (total_packet_count < max_packet_count) {
3544 if (test_ctx->exit_flag) {
3545 pr_info(TEST_MODULE_NAME ":%s exit test\n",
3546 __func__);
3547 return;
3548 }
3549 test_ch->buf[0] = total_packet_count;
3550 random_num = get_random_int();
3551 curr_burst_size = (random_num %
3552 test_ch->max_burst_size) + 1;
3553
3554 /* limit burst size to send
3555 * no more than configured packets */
3556 if (curr_burst_size + total_packet_count >
3557 max_packet_count) {
3558 curr_burst_size = max_packet_count -
3559 total_packet_count;
3560 }
3561 TEST_DBG(TEST_MODULE_NAME ":%s Current burst size:%d"
3562 " on chan %s\n", __func__,
3563 curr_burst_size, test_ch->name);
3564 ret = write_packet_burst(test_ch, curr_burst_size);
3565 if (ret) {
3566 pr_err(TEST_MODULE_NAME ":%s write burst failed (%d), ch %s\n",
3567 __func__, ret, test_ch->name);
3568 goto exit_err;
3569 }
3570 if (i > 0) {
3571 /* read from channel */
Maya Ereze05fc4d2011-09-11 14:18:43 +03003572 if (test_ch->ch->is_packet_mode)
3573 ret = read_data_from_packet_ch(test_ch,
3574 size,
3575 total_packet_count);
3576 else
3577 ret = read_data_from_stream_ch(test_ch,
3578 size,
3579 total_packet_count);
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003580 if (ret) {
3581 pr_err(TEST_MODULE_NAME ":%s read"
3582 " failed:%d, chan %s\n",
3583 __func__, ret,
3584 test_ch->name);
3585 goto exit_err;
3586 }
3587 }
3588 TEST_DBG(TEST_MODULE_NAME ":%s before close, ch %s\n",
3589 __func__, test_ch->name);
Maya Erezefafaa82011-09-21 12:41:28 +03003590 ret = close_sdio_ch(test_ch);
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003591 if (ret) {
3592 pr_err(TEST_MODULE_NAME":%s close channel %s"
3593 " failed (%d)\n",
3594 __func__, test_ch->name, ret);
3595 goto exit_err;
3596 } else {
3597 TEST_DBG(TEST_MODULE_NAME":%s close channel %s"
3598 " success\n", __func__,
3599 test_ch->name);
3600 total_packet_count += curr_burst_size;
3601 atomic_set(&test_ch->rx_notify_count, 0);
3602 atomic_set(&test_ch->tx_notify_count, 0);
3603 atomic_set(&test_ch->any_notify_count, 0);
3604 }
3605 TEST_DBG(TEST_MODULE_NAME ":%s before open, ch %s\n",
3606 __func__, test_ch->name);
Maya Erezefafaa82011-09-21 12:41:28 +03003607 ret = open_sdio_ch(test_ch);
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003608 if (ret) {
3609 pr_err(TEST_MODULE_NAME":%s open channel %s"
3610 " failed (%d)\n",
3611 __func__, test_ch->name, ret);
3612 goto exit_err;
3613 } else {
3614 read_avail = sdio_read_avail(test_ch->ch);
3615 if (read_avail > 0) {
3616 pr_err(TEST_MODULE_NAME": after open"
3617 " ch %s read_availis not zero"
3618 " (%d bytes)\n",
3619 test_ch->name, read_avail);
3620 goto exit_err;
3621 }
3622 }
3623 TEST_DBG(TEST_MODULE_NAME ":%s total tx = %d,"
3624 " packet# = %d, size = %d for ch %s\n",
3625 __func__, test_ch->tx_bytes,
3626 total_packet_count, size,
3627 test_ch->name);
3628 } /* end of while */
3629 }
3630 pr_info(TEST_MODULE_NAME ":%s Test end: total rx bytes = 0x%x,"
3631 " total tx bytes = 0x%x for chan %s\n", __func__,
3632 test_ch->rx_bytes, test_ch->tx_bytes, test_ch->name);
3633 pr_info(TEST_MODULE_NAME ":%s TEST PASS for chan %s.\n", __func__,
3634 test_ch->name);
3635 test_ch->test_completed = 1;
3636 test_ch->test_result = TEST_PASSED;
3637 check_test_completion();
3638 return;
3639exit_err:
3640 pr_info(TEST_MODULE_NAME ":%s TEST FAIL for chan %s.\n", __func__,
3641 test_ch->name);
3642 test_ch->test_completed = 1;
3643 test_ch->test_result = TEST_FAILED;
3644 check_test_completion();
3645 return;
3646}
3647
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003648/**
3649 * sender Test
3650 */
3651static void sender_test(struct test_channel *test_ch)
3652{
3653 int ret = 0 ;
3654 u32 read_avail = 0;
3655 u32 write_avail = 0;
3656 int packet_count = 0;
3657 int size = 512;
3658 u16 *buf16 = (u16 *) test_ch->buf;
3659 int i;
3660 int max_packet_count = 10000;
3661 int random_num = 0;
3662
3663 max_packet_count = test_ch->config_msg.num_packets;
3664
3665 for (i = 0 ; i < size / 2 ; i++)
3666 buf16[i] = (u16) (i & 0xFFFF);
3667
3668
3669 pr_info(TEST_MODULE_NAME
3670 ":SENDER TEST START for chan %s\n", test_ch->name);
3671
3672 while (packet_count < max_packet_count) {
3673
3674 if (test_ctx->exit_flag) {
3675 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
3676 return;
3677 }
3678
3679 random_num = get_random_int();
3680 size = (random_num % test_ch->packet_length) + 1;
3681
3682 TEST_DBG(TEST_MODULE_NAME "SENDER WAIT FOR EVENT for chan %s\n",
3683 test_ch->name);
3684
3685 /* wait for data ready event */
3686 write_avail = sdio_write_avail(test_ch->ch);
3687 TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
3688 if (write_avail < size) {
3689 wait_event(test_ch->wait_q,
3690 atomic_read(&test_ch->tx_notify_count));
3691 atomic_dec(&test_ch->tx_notify_count);
3692 }
3693
3694 write_avail = sdio_write_avail(test_ch->ch);
3695 TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
3696 if (write_avail < size) {
3697 pr_info(TEST_MODULE_NAME ":not enough write avail.\n");
3698 continue;
3699 }
3700
3701 test_ch->buf[0] = packet_count;
3702
3703 ret = sdio_write(test_ch->ch, test_ch->buf, size);
3704 if (ret) {
3705 pr_info(TEST_MODULE_NAME ":sender sdio_write err=%d.\n",
3706 -ret);
3707 goto exit_err;
3708 }
3709
3710 /* wait for read data ready event */
3711 TEST_DBG(TEST_MODULE_NAME ":sender wait for rx data for "
3712 "chan %s\n",
3713 test_ch->name);
3714 read_avail = sdio_read_avail(test_ch->ch);
3715 wait_event(test_ch->wait_q,
3716 atomic_read(&test_ch->rx_notify_count));
3717 atomic_dec(&test_ch->rx_notify_count);
3718
3719 read_avail = sdio_read_avail(test_ch->ch);
3720
3721 if (read_avail != size) {
3722 pr_info(TEST_MODULE_NAME
3723 ":read_avail size %d for chan %s not as "
3724 "expected size %d.\n",
3725 read_avail, test_ch->name, size);
3726 goto exit_err;
3727 }
3728
3729 memset(test_ch->buf, 0x00, size);
3730
3731 ret = sdio_read(test_ch->ch, test_ch->buf, size);
3732 if (ret) {
3733 pr_info(TEST_MODULE_NAME ":sender sdio_read for chan %s"
3734 " err=%d.\n",
3735 test_ch->name, -ret);
3736 goto exit_err;
3737 }
3738
3739
3740 if ((test_ch->buf[0] != packet_count) && (size != 1)) {
3741 pr_info(TEST_MODULE_NAME ":sender sdio_read WRONG DATA"
3742 " for chan %s, size=%d\n",
3743 test_ch->name, size);
3744 goto exit_err;
3745 }
3746
3747 test_ch->tx_bytes += size;
3748 test_ch->rx_bytes += size;
3749 packet_count++;
3750
3751 TEST_DBG(TEST_MODULE_NAME
3752 ":sender total rx bytes = 0x%x , packet#=%d, size=%d"
3753 " for chan %s\n",
3754 test_ch->rx_bytes, packet_count, size, test_ch->name);
3755 TEST_DBG(TEST_MODULE_NAME
3756 ":sender total tx bytes = 0x%x , packet#=%d, size=%d"
3757 " for chan %s\n",
3758 test_ch->tx_bytes, packet_count, size, test_ch->name);
3759
3760 } /* end of while */
3761
3762 pr_info(TEST_MODULE_NAME
3763 ":SENDER TEST END: total rx bytes = 0x%x, "
3764 " total tx bytes = 0x%x for chan %s\n",
3765 test_ch->rx_bytes, test_ch->tx_bytes, test_ch->name);
3766
3767 pr_info(TEST_MODULE_NAME ": TEST PASS for chan %s.\n",
3768 test_ch->name);
3769 test_ch->test_completed = 1;
3770 test_ch->test_result = TEST_PASSED;
3771 check_test_completion();
3772 return;
3773
3774exit_err:
3775 pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
3776 test_ch->name);
3777 test_ch->test_completed = 1;
3778 test_ch->test_result = TEST_FAILED;
3779 check_test_completion();
3780 return;
3781}
3782
3783/**
3784 * A2 Perf Test
3785 */
3786static void a2_performance_test(struct test_channel *test_ch)
3787{
3788 int ret = 0 ;
3789 u32 read_avail = 0;
3790 u32 write_avail = 0;
3791 int tx_packet_count = 0;
3792 int rx_packet_count = 0;
3793 int size = 0;
3794 u16 *buf16 = (u16 *) test_ch->buf;
3795 int i;
3796 int total_bytes = 0;
3797 int max_packets = 10000;
3798 u32 packet_size = test_ch->buf_size;
3799 int rand_size = 0;
3800
3801 u64 start_jiffy, end_jiffy, delta_jiffies;
3802 unsigned int time_msec = 0;
3803 u32 throughput = 0;
3804
3805 max_packets = test_ch->config_msg.num_packets;
3806 packet_size = test_ch->packet_length;
3807
3808 for (i = 0; i < packet_size / 2; i++)
3809 buf16[i] = (u16) (i & 0xFFFF);
3810
3811 pr_info(TEST_MODULE_NAME ": A2 PERFORMANCE TEST START for chan %s\n",
3812 test_ch->name);
3813
3814 start_jiffy = get_jiffies_64(); /* read the current time */
3815
3816 while (tx_packet_count < max_packets) {
3817
3818 if (test_ctx->exit_flag) {
3819 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
3820 return;
3821 }
3822
3823 if (test_ch->random_packet_size) {
3824 rand_size = get_random_int();
3825 packet_size = (rand_size % test_ch->packet_length) + 1;
3826 if (packet_size < A2_MIN_PACKET_SIZE)
3827 packet_size = A2_MIN_PACKET_SIZE;
3828 }
3829
3830 /* wait for data ready event */
3831 /* use a func to avoid compiler optimizations */
3832 write_avail = sdio_write_avail(test_ch->ch);
3833 read_avail = sdio_read_avail(test_ch->ch);
3834 TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d, "
3835 "read_avail=%d for chan %s\n",
3836 test_ch->name, write_avail, read_avail,
3837 test_ch->name);
3838 if ((write_avail == 0) && (read_avail == 0)) {
3839 wait_event(test_ch->wait_q,
3840 atomic_read(&test_ch->any_notify_count));
3841 atomic_set(&test_ch->any_notify_count, 0);
3842 }
3843
3844 write_avail = sdio_write_avail(test_ch->ch);
3845 TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d\n",
3846 test_ch->name, write_avail);
3847 if (write_avail > 0) {
3848 size = min(packet_size, write_avail) ;
3849 TEST_DBG(TEST_MODULE_NAME ":tx size = %d for chan %s\n",
3850 size, test_ch->name);
3851 test_ch->buf[0] = tx_packet_count;
3852 test_ch->buf[(size/4)-1] = tx_packet_count;
3853
3854 ret = sdio_write(test_ch->ch, test_ch->buf, size);
3855 if (ret) {
3856 pr_info(TEST_MODULE_NAME ":sdio_write err=%d"
3857 " for chan %s\n",
3858 -ret, test_ch->name);
3859 goto exit_err;
3860 }
3861 tx_packet_count++;
3862 test_ch->tx_bytes += size;
3863 }
3864
3865 read_avail = sdio_read_avail(test_ch->ch);
3866 TEST_DBG(TEST_MODULE_NAME ":channel %s, read_avail=%d\n",
3867 test_ch->name, read_avail);
3868 if (read_avail > 0) {
3869 size = min(packet_size, read_avail);
3870 pr_debug(TEST_MODULE_NAME ":rx size = %d.\n", size);
3871 ret = sdio_read(test_ch->ch, test_ch->buf, size);
3872 if (ret) {
3873 pr_info(TEST_MODULE_NAME ": sdio_read size %d "
3874 " err=%d"
3875 " for chan %s\n",
3876 size, -ret, test_ch->name);
3877 goto exit_err;
3878 }
3879 rx_packet_count++;
3880 test_ch->rx_bytes += size;
3881 }
3882
3883 TEST_DBG(TEST_MODULE_NAME
3884 ":total rx bytes = %d , rx_packet#=%d"
3885 " for chan %s\n",
3886 test_ch->rx_bytes, rx_packet_count, test_ch->name);
3887 TEST_DBG(TEST_MODULE_NAME
3888 ":total tx bytes = %d , tx_packet#=%d"
3889 " for chan %s\n",
3890 test_ch->tx_bytes, tx_packet_count, test_ch->name);
3891
3892 } /* while (tx_packet_count < max_packets ) */
3893
3894 end_jiffy = get_jiffies_64(); /* read the current time */
3895
3896 delta_jiffies = end_jiffy - start_jiffy;
3897 time_msec = jiffies_to_msecs(delta_jiffies);
3898
3899 pr_info(TEST_MODULE_NAME ":total rx bytes = 0x%x , rx_packet#=%d for"
3900 " chan %s.\n",
3901 test_ch->rx_bytes, rx_packet_count, test_ch->name);
3902 pr_info(TEST_MODULE_NAME ":total tx bytes = 0x%x , tx_packet#=%d"
3903 " for chan %s.\n",
3904 test_ch->tx_bytes, tx_packet_count, test_ch->name);
3905
3906 total_bytes = (test_ch->tx_bytes + test_ch->rx_bytes);
3907 pr_err(TEST_MODULE_NAME ":total bytes = %d, time msec = %d"
3908 " for chan %s\n",
3909 total_bytes , (int) time_msec, test_ch->name);
3910
3911 if (!test_ch->random_packet_size) {
3912 throughput = (total_bytes / time_msec) * 8 / 1000;
3913 pr_err(TEST_MODULE_NAME ":Performance = %d Mbit/sec for "
3914 "chan %s\n",
3915 throughput, test_ch->name);
3916 }
3917
3918#ifdef CONFIG_DEBUG_FS
3919 switch (test_ch->ch_id) {
3920 case SDIO_DUN:
3921 test_ctx->debug.dun_throughput = throughput;
3922 break;
3923 case SDIO_RMNT:
3924 test_ctx->debug.rmnt_throughput = throughput;
3925 break;
3926 default:
3927 pr_err(TEST_MODULE_NAME "No debugfs for this channel "
3928 "throughput");
3929 }
3930#endif
3931
3932 pr_err(TEST_MODULE_NAME ": A2 PERFORMANCE TEST END for chan %s.\n",
3933 test_ch->name);
3934
3935 pr_err(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
3936 test_ch->test_completed = 1;
3937 test_ch->test_result = TEST_PASSED;
3938 check_test_completion();
3939 return;
3940
3941exit_err:
3942 pr_err(TEST_MODULE_NAME ": TEST FAIL for chan %s\n", test_ch->name);
3943 test_ch->test_completed = 1;
3944 test_ch->test_result = TEST_FAILED;
3945 check_test_completion();
3946 return;
3947}
3948
3949/**
Maya Erez53508c12011-08-01 14:04:03 +03003950 * rx_cleanup
3951 * This function reads all the messages sent by the modem until
3952 * the read_avail is 0 after 1 second of sleep.
3953 * The function returns the number of packets that was received.
3954 */
3955static void rx_cleanup(struct test_channel *test_ch, int *rx_packet_count)
3956{
3957 int read_avail = 0;
3958 int ret = 0;
Maya Ereze05fc4d2011-09-11 14:18:43 +03003959 int counter = 0;
3960
3961 if (!test_ch || !test_ch->ch) {
3962 pr_err(TEST_MODULE_NAME ":%s NULL channel\n",
3963 __func__);
3964 return;
3965 }
Maya Erez53508c12011-08-01 14:04:03 +03003966
3967 read_avail = sdio_read_avail(test_ch->ch);
3968 TEST_DBG(TEST_MODULE_NAME ":channel %s, read_avail=%d\n",
3969 test_ch->name, read_avail);
3970
3971 /* If no pending messages, wait to see if the modem sends data */
3972 if (read_avail == 0) {
3973 msleep(1000);
3974 read_avail = sdio_read_avail(test_ch->ch);
3975 }
3976
Maya Ereze05fc4d2011-09-11 14:18:43 +03003977 while ((read_avail > 0) && (counter < 10)) {
Maya Erez53508c12011-08-01 14:04:03 +03003978 TEST_DBG(TEST_MODULE_NAME ": read_avail=%d for ch %s\n",
3979 read_avail, test_ch->name);
3980
3981 ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
3982 if (ret) {
3983 pr_info(TEST_MODULE_NAME ": sdio_read size %d "
3984 " err=%d for chan %s\n",
3985 read_avail, -ret, test_ch->name);
3986 break;
3987 }
3988 (*rx_packet_count)++;
3989 test_ch->rx_bytes += read_avail;
3990 read_avail = sdio_read_avail(test_ch->ch);
3991 if (read_avail == 0) {
3992 msleep(1000);
Maya Ereze05fc4d2011-09-11 14:18:43 +03003993 counter++;
Maya Erez53508c12011-08-01 14:04:03 +03003994 read_avail = sdio_read_avail(test_ch->ch);
3995 }
3996 }
3997 pr_info(TEST_MODULE_NAME ": finished cleanup for ch %s, "
3998 "rx_packet_count=%d, total rx bytes=%d\n",
3999 test_ch->name, *rx_packet_count, test_ch->rx_bytes);
4000}
4001
4002
4003/**
4004 * A2 RTT Test
4005 * This function sends a packet and calculate the RTT time of
4006 * this packet.
4007 * The test also calculte Min, Max and Average RTT
4008 */
4009static void a2_rtt_test(struct test_channel *test_ch)
4010{
4011 int ret = 0 ;
4012 u32 read_avail = 0;
4013 u32 write_avail = 0;
4014 int tx_packet_count = 0;
4015 int rx_packet_count = 0;
4016 u16 *buf16 = (u16 *) test_ch->buf;
4017 int i;
4018 int max_packets = test_ch->config_msg.num_packets;
4019 u32 packet_size = test_ch->packet_length;
4020 s64 start_time, end_time;
4021 int delta_usec = 0;
4022 int time_average = 0;
4023 int min_delta_usec = 0xFFFF;
4024 int max_delta_usec = 0;
4025 int total_time = 0;
4026 int expected_read_size = 0;
4027
4028 for (i = 0; i < packet_size / 2; i++)
4029 buf16[i] = (u16) (i & 0xFFFF);
4030
4031 pr_info(TEST_MODULE_NAME ": A2 RTT TEST START for chan %s\n",
4032 test_ch->name);
4033
Maya Erez2e2a9f62011-09-08 08:56:22 +03004034 /* Cleanup the pending RX data (such as loopback of te config msg) */
4035 rx_cleanup(test_ch, &rx_packet_count);
Maya Erez53508c12011-08-01 14:04:03 +03004036 rx_packet_count = 0;
4037
4038 while (tx_packet_count < max_packets) {
4039 if (test_ctx->exit_flag) {
4040 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
4041 return;
4042 }
4043 start_time = 0;
4044 end_time = 0;
4045
4046 /* Allow sdio_al to go to sleep to change the read_threshold
4047 * to 1
4048 */
4049 msleep(100);
4050
4051 /* wait for data ready event */
4052 write_avail = sdio_write_avail(test_ch->ch);
4053 TEST_DBG(TEST_MODULE_NAME ":ch %s: write_avail=%d\n",
4054 test_ch->name, write_avail);
4055 if (write_avail == 0) {
4056 wait_event(test_ch->wait_q,
4057 atomic_read(&test_ch->tx_notify_count));
4058 atomic_dec(&test_ch->tx_notify_count);
4059 }
4060
4061 write_avail = sdio_write_avail(test_ch->ch);
4062 TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d\n",
4063 test_ch->name, write_avail);
4064 if (write_avail > 0) {
4065 TEST_DBG(TEST_MODULE_NAME ":tx size = %d for chan %s\n",
4066 packet_size, test_ch->name);
4067 test_ch->buf[0] = tx_packet_count;
4068
4069 start_time = ktime_to_us(ktime_get());
4070 ret = sdio_write(test_ch->ch, test_ch->buf,
4071 packet_size);
4072 if (ret) {
4073 pr_err(TEST_MODULE_NAME ":sdio_write err=%d"
4074 " for chan %s\n",
4075 -ret, test_ch->name);
4076 goto exit_err;
4077 }
4078 tx_packet_count++;
4079 test_ch->tx_bytes += packet_size;
4080 } else {
4081 pr_err(TEST_MODULE_NAME ": Invalid write_avail"
4082 " %d for chan %s\n",
4083 write_avail, test_ch->name);
4084 goto exit_err;
4085 }
4086
4087 expected_read_size = packet_size + A2_HEADER_OVERHEAD;
4088
4089 read_avail = sdio_read_avail(test_ch->ch);
4090 TEST_DBG(TEST_MODULE_NAME ":channel %s, read_avail=%d\n",
4091 test_ch->name, read_avail);
4092 while (read_avail < expected_read_size) {
4093 wait_event(test_ch->wait_q,
4094 atomic_read(&test_ch->rx_notify_count));
4095 atomic_dec(&test_ch->rx_notify_count);
4096 read_avail = sdio_read_avail(test_ch->ch);
4097 }
4098
4099 if (read_avail >= expected_read_size) {
4100 pr_debug(TEST_MODULE_NAME ":read_avail=%d for ch %s.\n",
4101 read_avail, test_ch->name);
4102 ret = sdio_read(test_ch->ch, test_ch->buf,
4103 expected_read_size);
4104 if (ret) {
4105 pr_info(TEST_MODULE_NAME ": sdio_read size %d "
4106 " err=%d for chan %s\n",
4107 expected_read_size, -ret,
4108 test_ch->name);
4109 goto exit_err;
4110 }
4111 end_time = ktime_to_us(ktime_get());
4112 rx_packet_count++;
4113 test_ch->rx_bytes += expected_read_size;
4114 } else {
4115 pr_info(TEST_MODULE_NAME ": Invalid read_avail "
4116 "%d for chan %s\n",
4117 read_avail, test_ch->name);
4118 goto exit_err;
4119 }
4120
4121 delta_usec = (int)(end_time - start_time);
4122 total_time += delta_usec;
4123 if (delta_usec < min_delta_usec)
4124 min_delta_usec = delta_usec;
4125 if (delta_usec > max_delta_usec)
4126 max_delta_usec = delta_usec;
4127
4128 TEST_DBG(TEST_MODULE_NAME
4129 ":RTT time=%d for packet #%d for chan %s\n",
4130 delta_usec, tx_packet_count, test_ch->name);
4131
4132 } /* while (tx_packet_count < max_packets ) */
4133
4134
4135 pr_info(TEST_MODULE_NAME ":total rx bytes = 0x%x , rx_packet#=%d for"
4136 " chan %s.\n",
4137 test_ch->rx_bytes, rx_packet_count, test_ch->name);
4138 pr_info(TEST_MODULE_NAME ":total tx bytes = 0x%x , tx_packet#=%d"
4139 " for chan %s.\n",
4140 test_ch->tx_bytes, tx_packet_count, test_ch->name);
4141
4142 time_average = total_time / tx_packet_count;
4143
4144 pr_info(TEST_MODULE_NAME ":Average RTT time = %d for chan %s\n",
4145 time_average, test_ch->name);
4146 pr_info(TEST_MODULE_NAME ":MIN RTT time = %d for chan %s\n",
4147 min_delta_usec, test_ch->name);
4148 pr_info(TEST_MODULE_NAME ":MAX RTT time = %d for chan %s\n",
4149 max_delta_usec, test_ch->name);
4150
4151 pr_info(TEST_MODULE_NAME ": A2 RTT TEST END for chan %s.\n",
4152 test_ch->name);
4153
4154 pr_info(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
4155 test_ch->test_completed = 1;
4156 test_ch->test_result = TEST_PASSED;
4157 check_test_completion();
4158 return;
4159
4160exit_err:
4161 pr_err(TEST_MODULE_NAME ": TEST FAIL for chan %s\n", test_ch->name);
4162 test_ch->test_completed = 1;
4163 test_ch->test_result = TEST_FAILED;
4164 check_test_completion();
4165 return;
4166}
4167
4168
4169/**
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004170 * sender No loopback Test
4171 */
4172static void sender_no_loopback_test(struct test_channel *test_ch)
4173{
4174 int ret = 0 ;
4175 u32 write_avail = 0;
4176 int packet_count = 0;
4177 int size = 512;
4178 u16 *buf16 = (u16 *) test_ch->buf;
4179 int i;
4180 int max_packet_count = 10000;
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03004181 unsigned int random_num = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004182
4183 max_packet_count = test_ch->config_msg.num_packets;
4184
4185 for (i = 0 ; i < size / 2 ; i++)
4186 buf16[i] = (u16) (i & 0xFFFF);
4187
4188 pr_info(TEST_MODULE_NAME
4189 ":SENDER NO LP TEST START for chan %s\n", test_ch->name);
4190
4191 while (packet_count < max_packet_count) {
4192
4193 if (test_ctx->exit_flag) {
4194 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
4195 return;
4196 }
4197
4198 random_num = get_random_int();
4199 size = (random_num % test_ch->packet_length) + 1;
4200
4201 TEST_DBG(TEST_MODULE_NAME ":SENDER WAIT FOR EVENT "
4202 "for chan %s\n",
4203 test_ch->name);
4204
4205 /* wait for data ready event */
4206 write_avail = sdio_write_avail(test_ch->ch);
4207 TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
4208 if (write_avail < size) {
4209 wait_event(test_ch->wait_q,
4210 atomic_read(&test_ch->tx_notify_count));
4211 atomic_dec(&test_ch->tx_notify_count);
4212 }
4213
4214 write_avail = sdio_write_avail(test_ch->ch);
4215 TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
4216 if (write_avail < size) {
4217 pr_info(TEST_MODULE_NAME ":not enough write avail.\n");
4218 continue;
4219 }
4220
4221 test_ch->buf[0] = packet_count;
4222
4223 ret = sdio_write(test_ch->ch, test_ch->buf, size);
4224 if (ret) {
4225 pr_info(TEST_MODULE_NAME ":sender sdio_write err=%d.\n",
4226 -ret);
4227 goto exit_err;
4228 }
4229
4230 test_ch->tx_bytes += size;
4231 packet_count++;
4232
4233 TEST_DBG(TEST_MODULE_NAME
4234 ":sender total tx bytes = 0x%x , packet#=%d, size=%d"
4235 " for chan %s\n",
4236 test_ch->tx_bytes, packet_count, size, test_ch->name);
4237
4238 } /* end of while */
4239
4240 pr_info(TEST_MODULE_NAME
4241 ":SENDER TEST END: total tx bytes = 0x%x, "
4242 " for chan %s\n",
4243 test_ch->tx_bytes, test_ch->name);
4244
Yaniv Gardi3e327762011-07-27 11:11:04 +03004245 test_ch->modem_result_per_chan = wait_for_result_msg(test_ch);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004246
Yaniv Gardi3e327762011-07-27 11:11:04 +03004247 if (test_ch->modem_result_per_chan) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004248 pr_info(TEST_MODULE_NAME ": TEST PASS for chan %s.\n",
4249 test_ch->name);
4250 test_ch->test_result = TEST_PASSED;
4251 } else {
4252 pr_info(TEST_MODULE_NAME ": TEST FAILURE for chan %s.\n",
4253 test_ch->name);
4254 test_ch->test_result = TEST_FAILED;
4255 }
4256 test_ch->test_completed = 1;
4257 check_test_completion();
4258 return;
4259
4260exit_err:
4261 pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
4262 test_ch->name);
4263 test_ch->test_completed = 1;
4264 test_ch->test_result = TEST_FAILED;
4265 check_test_completion();
4266 return;
4267}
4268
Maya Erez8afd564f2011-08-24 15:57:06 +03004269
4270/**
4271 * Modem reset Test
4272 * The test verifies that it finished sending all the packets
4273 * while there might be modem reset in the middle
4274 */
4275static void modem_reset_test(struct test_channel *test_ch)
4276{
4277 int ret = 0 ;
4278 u32 read_avail = 0;
4279 u32 write_avail = 0;
4280 int tx_packet_count = 0;
4281 int rx_packet_count = 0;
4282 int size = 0;
4283 u16 *buf16 = (u16 *) test_ch->buf;
4284 int i;
4285 int max_packets = 10000;
4286 u32 packet_size = test_ch->buf_size;
4287 int is_err = 0;
4288
4289 max_packets = test_ch->config_msg.num_packets;
4290 packet_size = test_ch->packet_length;
4291
4292 for (i = 0; i < packet_size / 2; i++)
4293 buf16[i] = (u16) (i & 0xFFFF);
4294
4295 pr_info(TEST_MODULE_NAME ": Modem Reset TEST START for chan %s\n",
4296 test_ch->name);
4297
4298 while (tx_packet_count < max_packets) {
4299
4300 if (test_ctx->exit_flag) {
4301 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
4302 return;
4303 }
4304
4305 if (test_ch->card_removed) {
4306 pr_info(TEST_MODULE_NAME ": card removal was detected "
4307 "for chan %s, tx_total=0x%x\n",
4308 test_ch->name, test_ch->tx_bytes);
4309 wait_event(test_ch->wait_q,
4310 atomic_read(&test_ch->card_detected_event));
4311 atomic_set(&test_ch->card_detected_event, 0);
4312 pr_info(TEST_MODULE_NAME ": card_detected_event "
4313 "for chan %s\n", test_ch->name);
4314 if (test_ch->card_removed)
4315 continue;
4316 is_err = 0;
4317 /* Need to wait for the modem to be ready */
4318 msleep(5000);
4319 pr_info(TEST_MODULE_NAME ": sending the config message "
4320 "for chan %s\n", test_ch->name);
4321 send_config_msg(test_ch);
4322 }
4323
4324 /* wait for data ready event */
4325 /* use a func to avoid compiler optimizations */
4326 write_avail = sdio_write_avail(test_ch->ch);
4327 read_avail = sdio_read_avail(test_ch->ch);
4328 TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d, "
4329 "read_avail=%d for chan %s\n",
4330 test_ch->name, write_avail, read_avail,
4331 test_ch->name);
4332 if ((write_avail == 0) && (read_avail == 0)) {
4333 wait_event(test_ch->wait_q,
4334 atomic_read(&test_ch->any_notify_count));
4335 atomic_set(&test_ch->any_notify_count, 0);
4336 }
4337 if (atomic_read(&test_ch->card_detected_event)) {
4338 atomic_set(&test_ch->card_detected_event, 0);
4339 pr_info(TEST_MODULE_NAME ": card_detected_event "
4340 "for chan %s, tx_total=0x%x\n",
4341 test_ch->name, test_ch->tx_bytes);
4342 if (test_ch->card_removed)
4343 continue;
4344 /* Need to wait for the modem to be ready */
4345 msleep(5000);
4346 is_err = 0;
4347 pr_info(TEST_MODULE_NAME ": sending the config message "
4348 "for chan %s\n", test_ch->name);
4349 send_config_msg(test_ch);
4350 }
4351
4352 write_avail = sdio_write_avail(test_ch->ch);
4353 TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d\n",
4354 test_ch->name, write_avail);
4355 if (write_avail > 0) {
4356 size = min(packet_size, write_avail) ;
4357 pr_debug(TEST_MODULE_NAME ":tx size = %d for chan %s\n",
4358 size, test_ch->name);
4359 test_ch->buf[0] = tx_packet_count;
4360 test_ch->buf[(size/4)-1] = tx_packet_count;
4361
4362 TEST_DBG(TEST_MODULE_NAME ":channel %s, sdio_write, "
4363 "size=%d\n", test_ch->name, size);
4364 if (is_err) {
4365 msleep(100);
4366 continue;
4367 }
4368 ret = sdio_write(test_ch->ch, test_ch->buf, size);
4369 if (ret) {
4370 pr_info(TEST_MODULE_NAME ":sdio_write err=%d"
4371 " for chan %s\n",
4372 -ret, test_ch->name);
4373 is_err = 1;
4374 msleep(20);
4375 continue;
4376 }
4377 tx_packet_count++;
4378 test_ch->tx_bytes += size;
4379 test_ch->config_msg.num_packets--;
4380 }
4381
4382 read_avail = sdio_read_avail(test_ch->ch);
4383 TEST_DBG(TEST_MODULE_NAME ":channel %s, read_avail=%d\n",
4384 test_ch->name, read_avail);
4385 if (read_avail > 0) {
4386 size = min(packet_size, read_avail);
4387 pr_debug(TEST_MODULE_NAME ":rx size = %d.\n", size);
4388 TEST_DBG(TEST_MODULE_NAME ":channel %s, sdio_read, "
4389 "size=%d\n", test_ch->name, size);
4390 if (is_err) {
4391 msleep(100);
4392 continue;
4393 }
4394 ret = sdio_read(test_ch->ch, test_ch->buf, size);
4395 if (ret) {
4396 pr_info(TEST_MODULE_NAME ": sdio_read size %d "
4397 " err=%d"
4398 " for chan %s\n",
4399 size, -ret, test_ch->name);
4400 is_err = 1;
4401 msleep(20);
4402 continue;
4403 }
4404 rx_packet_count++;
4405 test_ch->rx_bytes += size;
4406 }
4407
4408 TEST_DBG(TEST_MODULE_NAME
4409 ":total rx bytes = %d , rx_packet#=%d"
4410 " for chan %s\n",
4411 test_ch->rx_bytes, rx_packet_count, test_ch->name);
4412 TEST_DBG(TEST_MODULE_NAME
4413 ":total tx bytes = %d , tx_packet#=%d"
4414 " for chan %s\n",
4415 test_ch->tx_bytes, tx_packet_count, test_ch->name);
4416
4417 udelay(500);
4418
4419 } /* while (tx_packet_count < max_packets ) */
4420
Maya Erez8afd564f2011-08-24 15:57:06 +03004421 pr_info(TEST_MODULE_NAME ":total rx bytes = 0x%x , rx_packet#=%d for"
4422 " chan %s.\n",
4423 test_ch->rx_bytes, rx_packet_count, test_ch->name);
4424 pr_info(TEST_MODULE_NAME ":total tx bytes = 0x%x , tx_packet#=%d"
4425 " for chan %s.\n",
4426 test_ch->tx_bytes, tx_packet_count, test_ch->name);
4427
4428 pr_err(TEST_MODULE_NAME ": Modem Reset TEST END for chan %s.\n",
4429 test_ch->name);
4430
4431 pr_err(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
4432 test_ch->test_completed = 1;
4433 test_ch->test_result = TEST_PASSED;
4434 check_test_completion();
4435 return;
4436}
4437
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004438/**
4439 * Worker thread to handle the tests types
4440 */
4441static void worker(struct work_struct *work)
4442{
4443 struct test_channel *test_ch = NULL;
4444 struct test_work *test_work = container_of(work,
4445 struct test_work,
4446 work);
4447 int test_type = 0;
4448
4449 test_ch = test_work->test_ch;
4450
4451 if (test_ch == NULL) {
4452 pr_err(TEST_MODULE_NAME ":NULL test_ch\n");
4453 return;
4454 }
4455
4456 test_type = test_ch->test_type;
4457
4458 switch (test_type) {
4459 case SDIO_TEST_LOOPBACK_HOST:
4460 loopback_test(test_ch);
4461 break;
4462 case SDIO_TEST_LOOPBACK_CLIENT:
4463 sender_test(test_ch);
4464 break;
4465 case SDIO_TEST_PERF:
4466 a2_performance_test(test_ch);
4467 break;
4468 case SDIO_TEST_LPM_CLIENT_WAKER:
4469 lpm_test(test_ch);
4470 break;
4471 case SDIO_TEST_LPM_HOST_WAKER:
4472 lpm_test_host_waker(test_ch);
4473 break;
4474 case SDIO_TEST_HOST_SENDER_NO_LP:
4475 sender_no_loopback_test(test_ch);
4476 break;
4477 case SDIO_TEST_LPM_RANDOM:
4478 lpm_continuous_rand_test(test_ch);
Maya Erezf204e692011-08-12 22:00:13 +03004479 break;
Maya Erez53508c12011-08-01 14:04:03 +03004480 case SDIO_TEST_RTT:
4481 a2_rtt_test(test_ch);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004482 break;
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03004483 case SDIO_TEST_CLOSE_CHANNEL:
Maya Erezefafaa82011-09-21 12:41:28 +03004484 if (test_ch->ch_id != SDIO_SMEM)
4485 open_close_test(test_ch);
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03004486 break;
Maya Erez8afd564f2011-08-24 15:57:06 +03004487 case SDIO_TEST_MODEM_RESET:
4488 modem_reset_test(test_ch);
4489 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004490 default:
4491 pr_err(TEST_MODULE_NAME ":Bad Test type = %d.\n",
4492 (int) test_type);
4493 }
4494}
4495
4496
4497/**
4498 * Notification Callback
4499 *
4500 * Notify the worker
4501 *
4502 */
4503static void notify(void *priv, unsigned channel_event)
4504{
4505 struct test_channel *test_ch = (struct test_channel *) priv;
4506
Yaniv Gardi3e327762011-07-27 11:11:04 +03004507 pr_debug(TEST_MODULE_NAME ": %s - notify event=%d.\n",
4508 __func__, channel_event);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004509
4510 if (test_ch->ch == NULL) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03004511 pr_info(TEST_MODULE_NAME ": %s - notify before ch ready.\n",
4512 __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004513 return;
4514 }
4515
4516 switch (channel_event) {
4517 case SDIO_EVENT_DATA_READ_AVAIL:
4518 atomic_inc(&test_ch->rx_notify_count);
4519 atomic_set(&test_ch->any_notify_count, 1);
Yaniv Gardi3e327762011-07-27 11:11:04 +03004520 TEST_DBG(TEST_MODULE_NAME ": %s - SDIO_EVENT_DATA_READ_AVAIL, "
4521 "any_notify_count=%d, rx_notify_count=%d\n",
4522 __func__,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004523 atomic_read(&test_ch->any_notify_count),
4524 atomic_read(&test_ch->rx_notify_count));
Yaniv Gardi3e327762011-07-27 11:11:04 +03004525 /*
4526 * when there is pending data on a channel we would like to
4527 * turn on the bit mask that implies that there is pending
4528 * data for that channel on that deivce
4529 */
4530 if (test_ch->test_device != NULL &&
4531 test_ch->test_type == SDIO_TEST_LPM_RANDOM) {
4532 spin_lock_irqsave(&test_ch->test_device->lpm_array_lock,
4533 test_ch->test_device->
4534 lpm_array_lock_flags);
4535 test_ch->test_device->read_avail_mask |=
4536 test_ch->channel_mask_id;
4537 test_ch->notify_counter_per_chan++;
4538
4539 lpm_test_update_entry(test_ch, LPM_NOTIFY, "NOTIFY", 0);
4540 spin_unlock_irqrestore(&test_ch->test_device->
4541 lpm_array_lock,
4542 test_ch->test_device->
4543 lpm_array_lock_flags);
4544 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004545 break;
4546
4547 case SDIO_EVENT_DATA_WRITE_AVAIL:
4548 atomic_inc(&test_ch->tx_notify_count);
4549 atomic_set(&test_ch->any_notify_count, 1);
Yaniv Gardi3e327762011-07-27 11:11:04 +03004550 TEST_DBG(TEST_MODULE_NAME ": %s - SDIO_EVENT_DATA_WRITE_AVAIL, "
4551 "any_notify_count=%d, tx_notify_count=%d\n",
4552 __func__,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004553 atomic_read(&test_ch->any_notify_count),
4554 atomic_read(&test_ch->tx_notify_count));
4555 break;
4556
4557 default:
4558 BUG();
4559 }
4560 wake_up(&test_ch->wait_q);
4561
4562}
4563
4564#ifdef CONFIG_MSM_SDIO_SMEM
4565static int sdio_smem_test_cb(int event)
4566{
4567 struct test_channel *tch = test_ctx->test_ch_arr[SDIO_SMEM];
Maya Erezefafaa82011-09-21 12:41:28 +03004568 int i;
4569 int *smem_buf = (int *)test_ctx->smem_buf;
4570 uint32_t val = 0;
4571 int ret = 0;
4572
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004573 pr_debug(TEST_MODULE_NAME ":%s: Received event %d\n", __func__, event);
4574
Maya Erezefafaa82011-09-21 12:41:28 +03004575 if (!tch) {
4576 pr_err(TEST_MODULE_NAME ": %s NULL tch\n", __func__);
4577 return -EINVAL;
4578 }
4579
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004580 switch (event) {
4581 case SDIO_SMEM_EVENT_READ_DONE:
4582 tch->rx_bytes += SMEM_MAX_XFER_SIZE;
Maya Erezefafaa82011-09-21 12:41:28 +03004583 for (i = 0; i < SMEM_MAX_XFER_SIZE;) {
4584 val = (int)*smem_buf;
4585 if ((val != test_ctx->smem_counter) && tch->is_used) {
4586 pr_err(TEST_MODULE_NAME ":%s: Invalid value %d "
4587 "expected %d in smem arr",
4588 __func__, val, test_ctx->smem_counter);
4589 pr_err(TEST_MODULE_NAME ":SMEM test FAILED\n");
4590 tch->test_completed = 1;
4591 tch->test_result = TEST_FAILED;
4592 check_test_completion();
4593 ret = -EINVAL;
4594 goto exit;
4595 }
4596 i += 4;
4597 smem_buf++;
4598 test_ctx->smem_counter++;
4599 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004600 if (tch->rx_bytes >= 40000000) {
Maya Erezefafaa82011-09-21 12:41:28 +03004601 if ((!tch->test_completed) && tch->is_used) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004602 pr_info(TEST_MODULE_NAME ":SMEM test PASSED\n");
4603 tch->test_completed = 1;
4604 tch->test_result = TEST_PASSED;
4605 check_test_completion();
4606 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004607 }
4608 break;
4609 case SDIO_SMEM_EVENT_READ_ERR:
Maya Erezefafaa82011-09-21 12:41:28 +03004610 if (tch->is_used) {
4611 pr_err(TEST_MODULE_NAME ":Read overflow, "
4612 "SMEM test FAILED\n");
4613 tch->test_completed = 1;
4614 tch->test_result = TEST_FAILED;
4615 ret = -EIO;
4616 }
4617 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004618 default:
Maya Erezefafaa82011-09-21 12:41:28 +03004619 if (tch->is_used) {
4620 pr_err(TEST_MODULE_NAME ":Unhandled event %d\n", event);
4621 ret = -EINVAL;
4622 }
4623 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004624 }
Maya Erezefafaa82011-09-21 12:41:28 +03004625exit:
4626 return ret;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004627}
4628
Maya Erezefafaa82011-09-21 12:41:28 +03004629static int sdio_smem_open(struct sdio_smem_client *sdio_smem)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004630{
4631 int ret = 0;
4632
Maya Erezefafaa82011-09-21 12:41:28 +03004633 if (!sdio_smem) {
4634 pr_info(TEST_MODULE_NAME "%s: NULL sdio_smem_client\n",
4635 __func__);
4636 return -EINVAL;
4637 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004638
Maya Erezefafaa82011-09-21 12:41:28 +03004639 if (test_ctx->test_ch_arr[SDIO_SMEM]->ch_ready) {
4640 pr_info(TEST_MODULE_NAME "%s: SDIO_SMEM channel is already opened\n",
4641 __func__);
4642 return 0;
4643 }
4644
4645 test_ctx->test_ch_arr[SDIO_SMEM]->ch_ready = 1;
4646 sdio_smem->buf = test_ctx->smem_buf;
4647 sdio_smem->size = SMEM_MAX_XFER_SIZE;
4648 sdio_smem->cb_func = sdio_smem_test_cb;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004649 ret = sdio_smem_register_client();
4650 if (ret)
4651 pr_info(TEST_MODULE_NAME "%s: Error (%d) registering sdio_smem "
4652 "test client\n",
4653 __func__, ret);
Maya Erezefafaa82011-09-21 12:41:28 +03004654
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004655 return ret;
4656}
4657
Maya Erezefafaa82011-09-21 12:41:28 +03004658static int sdio_smem_test_probe(struct platform_device *pdev)
4659{
4660 test_ctx->sdio_smem = container_of(pdev, struct sdio_smem_client,
4661 plat_dev);
4662
4663 return sdio_smem_open(test_ctx->sdio_smem);
4664}
4665
Maya Erez8afd564f2011-08-24 15:57:06 +03004666static struct platform_driver sdio_smem_client_drv = {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004667 .probe = sdio_smem_test_probe,
4668 .driver = {
4669 .name = "SDIO_SMEM_CLIENT",
4670 .owner = THIS_MODULE,
4671 },
4672};
4673#endif
4674
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004675static void sdio_test_lpm_timeout_handler(unsigned long data)
4676{
4677 struct test_channel *tch = (struct test_channel *)data;
4678
4679 pr_info(TEST_MODULE_NAME ": %s - LPM TEST TIMEOUT Expired after "
4680 "%d ms\n", __func__, tch->timeout_ms);
4681 tch->test_completed = 1;
4682 pr_info(TEST_MODULE_NAME ": %s - tch->test_result = TEST_FAILED\n",
4683 __func__);
4684 tch->test_completed = 1;
4685 tch->test_result = TEST_FAILED;
4686 check_test_completion();
4687 return;
4688}
4689
4690static void sdio_test_lpm_timer_handler(unsigned long data)
4691{
4692 struct test_channel *tch = (struct test_channel *)data;
4693
4694 pr_info(TEST_MODULE_NAME ": %s - LPM TEST Timer Expired after "
4695 "%d ms\n", __func__, tch->timer_interval_ms);
4696
4697 if (!tch) {
4698 pr_err(TEST_MODULE_NAME ": %s - LPM TEST FAILED. "
4699 "tch is NULL\n", __func__);
4700 return;
4701 }
4702
4703 if (!tch->ch) {
4704 pr_err(TEST_MODULE_NAME ": %s - LPM TEST FAILED. tch->ch "
4705 "is NULL\n", __func__);
4706 tch->test_result = TEST_FAILED;
4707 return;
4708 }
4709
4710 /* Verfiy that we voted for sleep */
4711 if (tch->is_ok_to_sleep) {
4712 tch->test_result = TEST_PASSED;
4713 pr_info(TEST_MODULE_NAME ": %s - 8K voted for sleep\n",
4714 __func__);
4715 } else {
4716 tch->test_result = TEST_FAILED;
4717 pr_info(TEST_MODULE_NAME ": %s - 8K voted against sleep\n",
4718 __func__);
4719
4720 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03004721
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004722 sdio_al_unregister_lpm_cb(tch->sdio_al_device);
4723
4724 if (tch->test_type == SDIO_TEST_LPM_HOST_WAKER) {
4725 atomic_set(&tch->wakeup_client, 1);
4726 wake_up(&tch->wait_q);
4727 }
4728}
4729
4730int sdio_test_wakeup_callback(void *device_handle, int is_vote_for_sleep)
4731{
4732 int i = 0;
4733
4734 TEST_DBG(TEST_MODULE_NAME ": %s is_vote_for_sleep=%d!!!",
4735 __func__, is_vote_for_sleep);
4736
4737 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
4738 struct test_channel *tch = test_ctx->test_ch_arr[i];
4739
4740 if ((!tch) || (!tch->is_used) || (!tch->ch_ready))
4741 continue;
4742 if (tch->sdio_al_device == device_handle) {
4743 tch->is_ok_to_sleep = is_vote_for_sleep;
4744
Yaniv Gardi3e327762011-07-27 11:11:04 +03004745 if (tch->test_type == SDIO_TEST_LPM_RANDOM) {
4746 spin_lock_irqsave(&tch->test_device->
4747 lpm_array_lock,
4748 tch->test_device->
4749 lpm_array_lock_flags);
Yaniv Gardi3e327762011-07-27 11:11:04 +03004750 if (is_vote_for_sleep == 1)
4751 lpm_test_update_entry(tch,
4752 LPM_SLEEP,
4753 "SLEEP ", 0);
4754 else
4755 lpm_test_update_entry(tch,
4756 LPM_WAKEUP,
4757 "WAKEUP", 0);
4758
4759 spin_unlock_irqrestore(&tch->test_device->
4760 lpm_array_lock,
4761 tch->test_device->
4762 lpm_array_lock_flags);
4763 break;
4764 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004765 }
4766 }
4767
Yaniv Gardi3e327762011-07-27 11:11:04 +03004768 return 0;
4769}
4770
4771static int sdio_test_find_dev(struct test_channel *tch)
4772{
4773 int j;
4774 int null_index = -1;
4775
4776 for (j = 0 ; j < MAX_NUM_OF_SDIO_DEVICES; ++j) {
4777
4778 struct sdio_test_device *test_dev =
4779 &test_ctx->test_dev_arr[j];
4780
4781 if (test_dev->sdio_al_device == NULL) {
4782 if (null_index == -1)
4783 null_index = j;
4784 continue;
4785 }
4786
4787 if (test_dev->sdio_al_device ==
4788 tch->ch->sdio_al_dev) {
4789 test_dev->open_channels_counter_to_recv++;
4790 test_dev->open_channels_counter_to_send++;
4791 tch->test_device = test_dev;
4792 /* setting mask id for pending data for
4793 this channel */
4794 tch->channel_mask_id = test_dev->next_mask_id;
4795 test_dev->next_mask_id *= 2;
4796 pr_info(TEST_MODULE_NAME ": %s - channel %s "
4797 "got read_mask_id = 0x%x. device "
4798 "next_mask_id=0x%x",
4799 __func__, tch->name, tch->channel_mask_id,
4800 test_dev->next_mask_id);
4801 break;
4802 }
4803 }
4804
4805 /*
4806 * happens ones a new device is "discovered" while testing. i.e
4807 * if testing a few channels, a new deivce will be "discovered" once
4808 * the first channel of a device is being tested
4809 */
4810 if (j == MAX_NUM_OF_SDIO_DEVICES) {
4811
4812 struct sdio_test_device *test_dev =
4813 &test_ctx->
4814 test_dev_arr[null_index];
4815 test_dev->sdio_al_device =
4816 tch->ch->sdio_al_dev;
4817
4818 test_ctx->number_of_active_devices++;
4819 test_ctx->max_number_of_devices++;
4820 test_dev->open_channels_counter_to_recv++;
4821 test_dev->open_channels_counter_to_send++;
4822 test_dev->next_avail_entry_in_array = 0;
4823 tch->test_device = test_dev;
4824 tch->test_device->array_size =
4825 LPM_ARRAY_SIZE;
4826 test_dev->modem_result_per_dev = 1;
4827 tch->modem_result_per_chan = 0;
4828
4829 spin_lock_init(&test_dev->
4830 lpm_array_lock);
Yaniv Gardi3e327762011-07-27 11:11:04 +03004831
4832 if (tch->test_type == SDIO_TEST_LPM_RANDOM) {
Maya Erez8afd564f2011-08-24 15:57:06 +03004833 pr_err(MODULE_NAME ": %s - "
4834 "Allocating Msg Array for "
4835 "Maximum open channels for device (%d) "
4836 "Channels. Array has %d entries",
4837 __func__,
4838 LPM_MAX_OPEN_CHAN_PER_DEV,
4839 test_dev->array_size);
Yaniv Gardi3e327762011-07-27 11:11:04 +03004840
4841 test_dev->lpm_arr =
4842 kzalloc(sizeof(
4843 struct lpm_entry_type) *
4844 tch->
4845 test_device->array_size,
4846 GFP_KERNEL);
4847
4848 if (!test_dev->lpm_arr) {
4849 pr_err(MODULE_NAME ": %s - "
4850 "lpm_arr is NULL",
4851 __func__);
4852 return -ENOMEM;
4853 }
4854 }
4855
4856 /*
4857 * in new device, initialize next_mask_id, and setting
4858 * mask_id to the channel
4859 */
4860 test_dev->next_mask_id = 0x1;
4861 tch->channel_mask_id = test_dev->next_mask_id;
4862 test_dev->next_mask_id *= 2;
4863 pr_info(TEST_MODULE_NAME ": %s - channel %s got "
4864 "read_mask_id = 0x%x. device next_mask_id=0x%x",
4865 __func__,
4866 tch->name,
4867 tch->channel_mask_id,
4868 test_dev->next_mask_id);
4869 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004870
4871 return 0;
4872}
4873
Yaniv Gardi3e327762011-07-27 11:11:04 +03004874static void check_test_result(void)
4875{
4876 int result = 1;
4877 int i = 0;
4878
4879 test_ctx->max_number_of_devices = 0;
4880
4881 pr_info(TEST_MODULE_NAME ": %s - Woke Up\n", __func__);
4882
4883 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
4884 struct test_channel *tch = test_ctx->test_ch_arr[i];
4885
4886 if ((!tch) || (!tch->is_used) || (!tch->ch_ready))
4887 continue;
4888
4889 if (tch->test_type == SDIO_TEST_LPM_RANDOM)
4890 result &= tch->test_device->final_result_per_dev;
4891 else
4892 if (tch->test_result == TEST_FAILED) {
4893 pr_info(TEST_MODULE_NAME ": %s - "
4894 "Test FAILED\n", __func__);
4895 test_ctx->test_result = TEST_FAILED;
4896 pr_err(TEST_MODULE_NAME ": %s - "
4897 "test_result %d",
4898 __func__, test_ctx->test_result);
4899 return;
4900 }
4901 }
4902
4903 if (result == 0) {
4904 pr_info(TEST_MODULE_NAME ": %s - Test FAILED\n", __func__);
4905 test_ctx->test_result = TEST_FAILED;
4906 pr_err(TEST_MODULE_NAME ": %s - "
4907 "test_result %d",
4908 __func__, test_ctx->test_result);
4909 return;
4910 }
4911
4912 pr_info(TEST_MODULE_NAME ": %s - Test PASSED", __func__);
4913 test_ctx->test_result = TEST_PASSED;
4914 pr_err(TEST_MODULE_NAME ": %s - "
4915 "test_result %d",
4916 __func__, test_ctx->test_result);
4917 return;
4918}
4919
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004920/**
4921 * Test Main
4922 */
4923static int test_start(void)
4924{
4925 int ret = -ENOMEM;
4926 int i;
4927
4928 pr_debug(TEST_MODULE_NAME ":Starting Test ....\n");
4929
4930 test_ctx->test_completed = 0;
4931 test_ctx->test_result = TEST_NO_RESULT;
4932 test_ctx->debug.dun_throughput = 0;
4933 test_ctx->debug.rmnt_throughput = 0;
Yaniv Gardi3e327762011-07-27 11:11:04 +03004934 test_ctx->number_of_active_devices = 0;
4935
4936 pr_err(TEST_MODULE_NAME ": %s - test_result %d",
4937 __func__, test_ctx->test_result);
4938
4939 memset(test_ctx->test_dev_arr, 0,
4940 sizeof(struct sdio_test_device)*MAX_NUM_OF_SDIO_DEVICES);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004941
4942 /* Open The Channels */
4943 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
4944 struct test_channel *tch = test_ctx->test_ch_arr[i];
4945
4946 if ((!tch) || (!tch->is_used))
4947 continue;
4948
4949 tch->rx_bytes = 0;
4950 tch->tx_bytes = 0;
4951
4952 atomic_set(&tch->tx_notify_count, 0);
4953 atomic_set(&tch->rx_notify_count, 0);
4954 atomic_set(&tch->any_notify_count, 0);
4955 atomic_set(&tch->wakeup_client, 0);
4956
Yaniv Gardi3e327762011-07-27 11:11:04 +03004957 /* in case there are values left from previous tests */
4958 tch->notify_counter_per_chan = 0;
4959
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004960 memset(tch->buf, 0x00, tch->buf_size);
4961 tch->test_result = TEST_NO_RESULT;
4962
4963 tch->test_completed = 0;
4964
Maya Erezefafaa82011-09-21 12:41:28 +03004965 ret = open_sdio_ch(tch);
4966 if (ret)
4967 continue;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004968
Yaniv Gardi3e327762011-07-27 11:11:04 +03004969 if (tch->ch_id != SDIO_SMEM) {
4970 ret = sdio_test_find_dev(tch);
4971
4972 if (ret) {
4973 pr_err(TEST_MODULE_NAME ": %s - "
4974 "sdio_test_find_dev() returned with "
4975 "error", __func__);
4976 return -ENODEV;
4977 }
4978
4979 tch->sdio_al_device = tch->ch->sdio_al_dev;
4980 }
4981
4982 if ((tch->test_type == SDIO_TEST_LPM_HOST_WAKER) ||
4983 (tch->test_type == SDIO_TEST_LPM_CLIENT_WAKER) ||
4984 (tch->test_type == SDIO_TEST_LPM_RANDOM))
4985 sdio_al_register_lpm_cb(tch->sdio_al_device,
4986 sdio_test_wakeup_callback);
4987 }
4988
4989 /*
4990 * make some space between opening the channels and sending the
4991 * config messages
4992 */
4993 msleep(100);
4994
4995 /*
4996 * try to delay send_config_msg of all channels to after the point
4997 * when we open them all
4998 */
4999 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
5000 struct test_channel *tch = test_ctx->test_ch_arr[i];
5001
5002 if ((!tch) || (!tch->is_used))
5003 continue;
5004
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005005 if ((tch->ch_ready) && (tch->ch_id != SDIO_SMEM))
5006 send_config_msg(tch);
5007
5008 if ((tch->test_type == SDIO_TEST_LPM_HOST_WAKER) ||
5009 (tch->test_type == SDIO_TEST_LPM_CLIENT_WAKER) ||
5010 (tch->test_type == SDIO_TEST_LPM_RANDOM)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005011 if (tch->timer_interval_ms > 0) {
5012 pr_info(TEST_MODULE_NAME ": %s - init timer, "
Yaniv Gardi3e327762011-07-27 11:11:04 +03005013 "ms=%d\n",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005014 __func__, tch->timer_interval_ms);
5015 init_timer(&tch->timer);
5016 tch->timer.data = (unsigned long)tch;
5017 tch->timer.function =
5018 sdio_test_lpm_timer_handler;
5019 tch->timer.expires = jiffies +
5020 msecs_to_jiffies(tch->timer_interval_ms);
5021 add_timer(&tch->timer);
5022 }
5023 }
5024 }
5025
5026 pr_debug(TEST_MODULE_NAME ":queue_work..\n");
5027 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
5028 struct test_channel *tch = test_ctx->test_ch_arr[i];
5029
Maya Erezefafaa82011-09-21 12:41:28 +03005030 if ((!tch) || (!tch->is_used) || (!tch->ch_ready))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005031 continue;
Yaniv Gardi3e327762011-07-27 11:11:04 +03005032
Maya Erezefafaa82011-09-21 12:41:28 +03005033 if (tch->ch_id == SDIO_SMEM) {
5034#ifdef CONFIG_MSM_SDIO_SMEM
5035 if (tch->test_type == SDIO_TEST_CLOSE_CHANNEL)
5036 open_close_smem_test(tch);
5037#endif
5038 } else {
5039 queue_work(tch->workqueue, &tch->test_work.work);
5040 }
5041
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005042 }
5043
Yaniv Gardi3e327762011-07-27 11:11:04 +03005044 pr_info(TEST_MODULE_NAME ": %s - Waiting for the test completion\n",
5045 __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005046
Yaniv Gardi3e327762011-07-27 11:11:04 +03005047 wait_event(test_ctx->wait_q, test_ctx->test_completed);
5048 check_test_result();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005049
Maya Erez8afd564f2011-08-24 15:57:06 +03005050 /*
5051 * Close the channels and zero the is_used flag so that if the modem
5052 * will be reset after the test completion we won't re-open
5053 * the channels
5054 */
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03005055 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
5056 struct test_channel *tch = test_ctx->test_ch_arr[i];
5057
Maya Erez8afd564f2011-08-24 15:57:06 +03005058 if ((!tch) || (!tch->is_used))
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03005059 continue;
Maya Erezefafaa82011-09-21 12:41:28 +03005060 if (!tch->ch_ready) {
Maya Erez8afd564f2011-08-24 15:57:06 +03005061 tch->is_used = 0;
5062 continue;
5063 }
Maya Erezefafaa82011-09-21 12:41:28 +03005064
5065 close_sdio_ch(tch);
Maya Erez8afd564f2011-08-24 15:57:06 +03005066 tch->is_used = 0;
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03005067 }
Maya Ereze05fc4d2011-09-11 14:18:43 +03005068
5069 if (test_ctx->test_result == TEST_PASSED)
5070 return 0;
5071 else
5072 return -EINVAL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005073}
5074
5075static int set_params_loopback_9k(struct test_channel *tch)
5076{
5077 if (!tch) {
5078 pr_err(TEST_MODULE_NAME ":NULL channel\n");
5079 return -EINVAL;
5080 }
5081 tch->is_used = 1;
5082 tch->test_type = SDIO_TEST_LOOPBACK_CLIENT;
5083 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
5084 tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
5085 tch->config_msg.num_packets = 10000;
5086 tch->config_msg.num_iterations = 1;
5087
5088 tch->packet_length = 512;
5089 if (tch->ch_id == SDIO_RPC)
5090 tch->packet_length = 128;
5091 tch->timer_interval_ms = 0;
5092
5093 return 0;
5094}
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03005095static int set_params_loopback_9k_close(struct test_channel *tch)
5096{
5097 if (!tch) {
5098 pr_err(TEST_MODULE_NAME ":NULL channel\n");
5099 return -EINVAL;
5100 }
5101 tch->is_used = 1;
5102 tch->test_type = SDIO_TEST_CLOSE_CHANNEL;
5103 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
5104 tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
5105 tch->config_msg.num_packets = 5000;
5106 tch->config_msg.num_iterations = 1;
5107 tch->max_burst_size = 10;
5108 switch (tch->ch_id) {
5109 case SDIO_DUN:
5110 case SDIO_RPC:
5111 tch->packet_length = 128; /* max is 2K*/
5112 break;
5113 case SDIO_CIQ:
5114 case SDIO_DIAG:
5115 case SDIO_RMNT:
5116 default:
5117 tch->packet_length = 512; /* max is 4k */
5118 }
5119 tch->timer_interval_ms = 0;
5120 return 0;
5121}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005122static int set_params_a2_perf(struct test_channel *tch)
5123{
5124 if (!tch) {
5125 pr_err(TEST_MODULE_NAME ":NULL channel\n");
5126 return -EINVAL;
5127 }
5128 tch->is_used = 1;
5129 tch->test_type = SDIO_TEST_PERF;
5130 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
5131 tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
Maya Erezbde9df82011-08-02 14:40:00 +03005132 tch->packet_length = MAX_XFER_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005133 if (tch->ch_id == SDIO_DIAG)
5134 tch->packet_length = 512;
Maya Erezbde9df82011-08-02 14:40:00 +03005135 else if (tch->ch_id == SDIO_DUN)
5136 tch->packet_length = DUN_PACKET_SIZE;
5137 pr_info(TEST_MODULE_NAME ": %s: packet_length=%d", __func__,
5138 tch->packet_length);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005139
5140 tch->config_msg.num_packets = 10000;
5141 tch->config_msg.num_iterations = 1;
5142 tch->random_packet_size = 0;
5143
5144 tch->timer_interval_ms = 0;
5145
5146 return 0;
5147}
5148
Maya Erez53508c12011-08-01 14:04:03 +03005149static int set_params_rtt(struct test_channel *tch)
5150{
5151 if (!tch) {
5152 pr_err(TEST_MODULE_NAME ":NULL channel\n");
5153 return -EINVAL;
5154 }
5155 tch->is_used = 1;
5156 tch->test_type = SDIO_TEST_RTT;
5157 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
5158 tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
5159 tch->packet_length = 32;
5160
5161 tch->config_msg.num_packets = 200;
5162 tch->config_msg.num_iterations = 1;
5163 tch->random_packet_size = 0;
5164
5165 tch->timer_interval_ms = 0;
5166
5167 return 0;
5168}
5169
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005170static int set_params_a2_small_pkts(struct test_channel *tch)
5171{
5172 if (!tch) {
5173 pr_err(TEST_MODULE_NAME ":NULL channel\n");
5174 return -EINVAL;
5175 }
5176 tch->is_used = 1;
5177 tch->test_type = SDIO_TEST_PERF;
5178 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
5179 tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
5180 tch->packet_length = 128;
5181
5182 tch->config_msg.num_packets = 1000000;
5183 tch->config_msg.num_iterations = 1;
5184 tch->random_packet_size = 1;
5185
5186 tch->timer_interval_ms = 0;
5187
5188 return 0;
5189}
5190
Maya Erez8afd564f2011-08-24 15:57:06 +03005191static int set_params_modem_reset(struct test_channel *tch)
5192{
5193 if (!tch) {
5194 pr_err(TEST_MODULE_NAME ":NULL channel\n");
5195 return -EINVAL;
5196 }
5197 tch->is_used = 1;
5198 tch->test_type = SDIO_TEST_MODEM_RESET;
5199 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
5200 tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
5201 tch->packet_length = 512;
5202 if (tch->ch_id == SDIO_RPC)
5203 tch->packet_length = 128;
5204 else if ((tch->ch_id == SDIO_RMNT) || (tch->ch_id == SDIO_DUN))
5205 tch->packet_length = MAX_XFER_SIZE;
5206
5207 tch->config_msg.num_packets = 50000;
5208 tch->config_msg.num_iterations = 1;
5209
5210 tch->timer_interval_ms = 0;
5211
5212 return 0;
5213}
5214
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005215static int set_params_smem_test(struct test_channel *tch)
5216{
5217 if (!tch) {
5218 pr_err(TEST_MODULE_NAME ":NULL channel\n");
5219 return -EINVAL;
5220 }
5221 tch->is_used = 1;
5222 tch->timer_interval_ms = 0;
5223
5224 return 0;
5225}
5226
5227static int set_params_lpm_test(struct test_channel *tch,
5228 enum sdio_test_case_type test,
5229 int timer_interval_ms)
5230{
5231 static int first_time = 1;
5232 if (!tch) {
5233 pr_err(TEST_MODULE_NAME ": %s - NULL channel\n", __func__);
5234 return -EINVAL;
5235 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03005236
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005237 tch->is_used = 1;
5238 tch->test_type = test;
5239 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
5240 tch->config_msg.test_case = test;
Yaniv Gardi3e327762011-07-27 11:11:04 +03005241 tch->config_msg.num_packets = LPM_TEST_NUM_OF_PACKETS;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005242 tch->config_msg.num_iterations = 1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005243 tch->timer_interval_ms = timer_interval_ms;
5244 tch->timeout_ms = 10000;
5245
5246 tch->packet_length = 0;
5247 if (test != SDIO_TEST_LPM_RANDOM) {
5248 init_timer(&tch->timeout_timer);
5249 tch->timeout_timer.data = (unsigned long)tch;
5250 tch->timeout_timer.function = sdio_test_lpm_timeout_handler;
5251 tch->timeout_timer.expires = jiffies +
5252 msecs_to_jiffies(tch->timeout_ms);
5253 add_timer(&tch->timeout_timer);
5254 pr_info(TEST_MODULE_NAME ": %s - Initiated LPM TIMEOUT TIMER."
5255 "set to %d ms\n",
5256 __func__, tch->timeout_ms);
5257 }
5258
5259 if (first_time) {
5260 pr_info(TEST_MODULE_NAME ": %s - wake_lock_init() called\n",
5261 __func__);
5262 wake_lock_init(&test_ctx->wake_lock,
5263 WAKE_LOCK_SUSPEND, TEST_MODULE_NAME);
5264 first_time = 0;
5265 }
5266
5267 pr_info(TEST_MODULE_NAME ": %s - wake_lock() for the TEST is "
Yaniv Gardi3e327762011-07-27 11:11:04 +03005268 "called channel %s. to prevent real sleeping\n",
5269 __func__, tch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005270 wake_lock(&test_ctx->wake_lock);
5271
5272 return 0;
5273}
5274
5275static int set_params_8k_sender_no_lp(struct test_channel *tch)
5276{
5277 if (!tch) {
5278 pr_err(TEST_MODULE_NAME ":NULL channel\n");
5279 return -EINVAL;
5280 }
5281 tch->is_used = 1;
5282 tch->test_type = SDIO_TEST_HOST_SENDER_NO_LP;
5283 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
5284 tch->config_msg.test_case = SDIO_TEST_HOST_SENDER_NO_LP;
5285 tch->config_msg.num_packets = 1000;
5286 tch->config_msg.num_iterations = 1;
5287
5288 tch->packet_length = 512;
5289 if (tch->ch_id == SDIO_RPC)
5290 tch->packet_length = 128;
5291 tch->timer_interval_ms = 0;
5292
5293 return 0;
5294}
5295
Maya Erezf204e692011-08-12 22:00:13 +03005296static void set_pseudo_random_seed(void)
5297{
5298 /* Set the seed accoring to the kernel command parameters if any or
5299 get a random value */
5300 if (seed != 0) {
5301 test_ctx->lpm_pseudo_random_seed = seed;
5302 } else {
5303 test_ctx->lpm_pseudo_random_seed =
5304 (unsigned int)(get_jiffies_64() & 0xFFFF);
5305 test_ctx->lpm_pseudo_random_seed =
5306 pseudo_random_seed(&test_ctx->lpm_pseudo_random_seed);
5307 }
5308
5309 pr_info(TEST_MODULE_NAME ":%s: seed is %u",
5310 __func__, test_ctx->lpm_pseudo_random_seed);
5311}
5312
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03005313/*
5314 for each channel
5315 1. open channel
5316 2. close channel
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03005317*/
Yaniv Gardib4237782011-08-31 20:06:16 +03005318static int close_channel_lpm_test(int channel_num)
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03005319{
5320 int ret = 0;
5321 struct test_channel *tch = NULL;
Yaniv Gardib4237782011-08-31 20:06:16 +03005322 tch = test_ctx->test_ch_arr[channel_num];
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03005323
Maya Erezefafaa82011-09-21 12:41:28 +03005324 ret = open_sdio_ch(tch);
5325 if (ret) {
5326 pr_err(TEST_MODULE_NAME":%s open channel %s"
5327 " failed\n", __func__, tch->name);
5328 return ret;
5329 } else {
5330 pr_info(TEST_MODULE_NAME":%s open channel %s"
5331 " success\n", __func__, tch->name);
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03005332 }
Maya Erezefafaa82011-09-21 12:41:28 +03005333 ret = close_sdio_ch(tch);
Yaniv Gardib4237782011-08-31 20:06:16 +03005334 if (ret) {
5335 pr_err(TEST_MODULE_NAME":%s close channel %s"
5336 " failed\n", __func__, tch->name);
5337 return ret;
5338 } else {
5339 pr_info(TEST_MODULE_NAME":%s close channel %s"
5340 " success\n", __func__, tch->name);
Yaniv Gardib4237782011-08-31 20:06:16 +03005341 }
5342
5343 tch->is_used = 0;
5344
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03005345 return ret;
5346}
5347
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005348/**
5349 * Write File.
5350 *
5351 * @note Trigger the test from user space by:
5352 * echo 1 > /dev/sdio_al_test
5353 *
5354 */
5355ssize_t test_write(struct file *filp, const char __user *buf, size_t size,
5356 loff_t *f_pos)
5357{
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03005358 sdio_al_test_initial_dev_and_chan(test_ctx);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005359
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03005360 if (strict_strtol(buf, 10, &test_ctx->testcase))
5361 return -EINVAL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005362
5363 switch (test_ctx->testcase) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005364 case 98:
5365 pr_info(TEST_MODULE_NAME " set runtime debug on");
5366 test_ctx->runtime_debug = 1;
5367 return size;
5368 case 99:
5369 pr_info(TEST_MODULE_NAME " set runtime debug off");
5370 test_ctx->runtime_debug = 0;
5371 return size;
5372 default:
5373 pr_info(TEST_MODULE_NAME ":Bad Test number = %d.\n",
5374 (int)test_ctx->testcase);
Maya Erez8afd564f2011-08-24 15:57:06 +03005375 return size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005376 }
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03005377
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005378 return size;
5379}
5380
5381/**
5382 * Test Channel Init.
5383 */
5384int test_channel_init(char *name)
5385{
5386 struct test_channel *test_ch;
5387 int ch_id = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005388 int ret;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005389
5390 pr_debug(TEST_MODULE_NAME ":%s.\n", __func__);
5391 pr_info(TEST_MODULE_NAME ": init test cahnnel %s.\n", name);
5392
5393 ch_id = channel_name_to_id(name);
5394 pr_debug(TEST_MODULE_NAME ":id = %d.\n", ch_id);
5395 if (test_ctx->test_ch_arr[ch_id] == NULL) {
5396 test_ch = kzalloc(sizeof(*test_ch), GFP_KERNEL);
5397 if (test_ch == NULL) {
5398 pr_err(TEST_MODULE_NAME ":kzalloc err for allocating "
5399 "test_ch %s.\n",
5400 name);
5401 return -ENOMEM;
5402 }
5403 test_ctx->test_ch_arr[ch_id] = test_ch;
5404
5405 test_ch->ch_id = ch_id;
5406
Maya Erez8afd564f2011-08-24 15:57:06 +03005407 strncpy(test_ch->name, name,
5408 strnlen(name, TEST_CH_NAME_SIZE)-SDIO_TEST_POSTFIX_SIZE);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005409
5410 test_ch->buf_size = MAX_XFER_SIZE;
5411
5412 test_ch->buf = kzalloc(test_ch->buf_size, GFP_KERNEL);
5413 if (test_ch->buf == NULL) {
5414 kfree(test_ch);
5415 test_ctx->test_ch = NULL;
5416 return -ENOMEM;
5417 }
5418
5419 if (test_ch->ch_id == SDIO_SMEM) {
5420 test_ctx->smem_buf = kzalloc(SMEM_MAX_XFER_SIZE,
5421 GFP_KERNEL);
5422 if (test_ctx->smem_buf == NULL) {
5423 pr_err(TEST_MODULE_NAME ":%s: Unable to "
5424 "allocate smem buf\n",
5425 __func__);
5426 kfree(test_ch);
5427 test_ctx->test_ch = NULL;
5428 return -ENOMEM;
5429 }
5430
5431#ifdef CONFIG_MSM_SDIO_SMEM
Maya Erez8afd564f2011-08-24 15:57:06 +03005432 ret = platform_driver_register(&sdio_smem_client_drv);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005433 if (ret) {
5434 pr_err(TEST_MODULE_NAME ":%s: Unable to "
5435 "register sdio smem "
5436 "test client\n",
5437 __func__);
5438 return ret;
5439 }
5440#endif
5441 } else {
5442 test_ch->workqueue =
5443 create_singlethread_workqueue(test_ch->name);
5444 test_ch->test_work.test_ch = test_ch;
5445 INIT_WORK(&test_ch->test_work.work, worker);
5446
5447 init_waitqueue_head(&test_ch->wait_q);
5448 }
5449 } else {
Maya Erez8afd564f2011-08-24 15:57:06 +03005450 test_ch = test_ctx->test_ch_arr[ch_id];
5451 pr_info(TEST_MODULE_NAME ":%s: ch %s was detected again\n",
5452 __func__, test_ch->name);
5453 test_ch->card_removed = 0;
5454 if ((test_ch->is_used) &&
5455 (test_ch->test_type == SDIO_TEST_MODEM_RESET)) {
5456 if (test_ch->ch_id == SDIO_SMEM) {
Maya Erezefafaa82011-09-21 12:41:28 +03005457#ifdef CONFIG_MSM_SDIO_SMEM
5458 ret = add_sdio_smem();
5459 if (ret) {
5460 test_ch->ch_ready = false;
5461 return 0;
5462 }
5463#endif
Maya Erez8afd564f2011-08-24 15:57:06 +03005464 } else {
Maya Erezefafaa82011-09-21 12:41:28 +03005465 ret = open_sdio_ch(test_ch);
Maya Erez8afd564f2011-08-24 15:57:06 +03005466 if (ret) {
5467 pr_info(TEST_MODULE_NAME
Maya Erezefafaa82011-09-21 12:41:28 +03005468 ":%s: open channel %s failed\n",
5469 __func__, test_ch->name);
Maya Erez8afd564f2011-08-24 15:57:06 +03005470 return 0;
5471 }
5472 ret = sdio_test_find_dev(test_ch);
5473
5474 if (ret) {
5475 pr_err(TEST_MODULE_NAME ": %s - "
5476 "sdio_test_find_dev() returned "
5477 "with error", __func__);
5478 return -ENODEV;
5479 }
5480
5481 test_ch->sdio_al_device =
5482 test_ch->ch->sdio_al_dev;
5483 }
5484 atomic_set(&test_ch->card_detected_event, 1);
5485 wake_up(&test_ch->wait_q);
5486 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005487 }
5488
5489 return 0;
5490}
5491
Maya Erez8afd564f2011-08-24 15:57:06 +03005492static int sdio_test_channel_probe(struct platform_device *pdev)
5493{
5494 if (!pdev)
5495 return -EIO;
5496 return test_channel_init((char *)pdev->name);
5497}
5498
5499static int sdio_test_channel_remove(struct platform_device *pdev)
5500{
5501 int ch_id;
5502
5503 if (!pdev)
5504 return -EIO;
5505
5506 ch_id = channel_name_to_id((char *)pdev->name);
5507 if (test_ctx->test_ch_arr[ch_id] == NULL)
5508 return 0;
5509
5510 pr_info(TEST_MODULE_NAME "%s: remove ch %s\n",
5511 __func__, test_ctx->test_ch_arr[ch_id]->name);
Maya Erezefafaa82011-09-21 12:41:28 +03005512
5513 if ((ch_id == SDIO_SMEM) && (test_ctx->smem_pdev)) {
5514 platform_device_unregister(test_ctx->smem_pdev);
5515 test_ctx->smem_pdev = NULL;
5516 }
5517
Maya Erez8afd564f2011-08-24 15:57:06 +03005518 test_ctx->test_ch_arr[ch_id]->ch_ready = 0;
5519 test_ctx->test_ch_arr[ch_id]->card_removed = 1;
5520
5521 return 0;
5522
5523}
5524
5525static struct platform_driver sdio_rpc_drv = {
5526 .probe = sdio_test_channel_probe,
5527 .remove = sdio_test_channel_remove,
5528 .driver = {
5529 .name = "SDIO_RPC_TEST",
5530 .owner = THIS_MODULE,
5531 },
5532};
5533
5534static struct platform_driver sdio_qmi_drv = {
5535 .probe = sdio_test_channel_probe,
5536 .remove = sdio_test_channel_remove,
5537 .driver = {
5538 .name = "SDIO_QMI_TEST",
5539 .owner = THIS_MODULE,
5540 },
5541};
5542
5543static struct platform_driver sdio_diag_drv = {
5544 .probe = sdio_test_channel_probe,
5545 .remove = sdio_test_channel_remove,
5546 .driver = {
5547 .name = "SDIO_DIAG_TEST",
5548 .owner = THIS_MODULE,
5549 },
5550};
5551
5552static struct platform_driver sdio_smem_drv = {
5553 .probe = sdio_test_channel_probe,
5554 .remove = sdio_test_channel_remove,
5555 .driver = {
5556 .name = "SDIO_SMEM_TEST",
5557 .owner = THIS_MODULE,
5558 },
5559};
5560
5561static struct platform_driver sdio_rmnt_drv = {
5562 .probe = sdio_test_channel_probe,
5563 .remove = sdio_test_channel_remove,
5564 .driver = {
5565 .name = "SDIO_RMNT_TEST",
5566 .owner = THIS_MODULE,
5567 },
5568};
5569
5570static struct platform_driver sdio_dun_drv = {
5571 .probe = sdio_test_channel_probe,
5572 .remove = sdio_test_channel_remove,
5573 .driver = {
5574 .name = "SDIO_DUN_TEST",
5575 .owner = THIS_MODULE,
5576 },
5577};
5578
5579static struct platform_driver sdio_ciq_drv = {
5580 .probe = sdio_test_channel_probe,
5581 .remove = sdio_test_channel_remove,
5582 .driver = {
5583 .name = "SDIO_CIQ_TEST",
5584 .owner = THIS_MODULE,
5585 },
5586};
5587
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005588static struct class *test_class;
5589
5590const struct file_operations test_fops = {
5591 .owner = THIS_MODULE,
5592 .write = test_write,
5593};
5594
5595/**
5596 * Module Init.
5597 */
5598static int __init test_init(void)
5599{
5600 int ret;
5601
5602 pr_debug(TEST_MODULE_NAME ":test_init.\n");
5603
Yaniv Gardi3e327762011-07-27 11:11:04 +03005604 test_ctx = kzalloc(sizeof(struct test_context), GFP_KERNEL);
5605
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005606 if (test_ctx == NULL) {
5607 pr_err(TEST_MODULE_NAME ":kzalloc err.\n");
5608 return -ENOMEM;
5609 }
5610 test_ctx->test_ch = NULL;
5611 test_ctx->signature = TEST_SIGNATURE;
5612
5613 test_ctx->name = "UNKNOWN";
5614
5615 init_waitqueue_head(&test_ctx->wait_q);
5616
5617#ifdef CONFIG_DEBUG_FS
5618 sdio_al_test_debugfs_init();
5619#endif
5620
5621 test_class = class_create(THIS_MODULE, TEST_MODULE_NAME);
5622
5623 ret = alloc_chrdev_region(&test_ctx->dev_num, 0, 1, TEST_MODULE_NAME);
5624 if (ret) {
5625 pr_err(TEST_MODULE_NAME "alloc_chrdev_region err.\n");
5626 return -ENODEV;
5627 }
5628
5629 test_ctx->dev = device_create(test_class, NULL, test_ctx->dev_num,
5630 test_ctx, TEST_MODULE_NAME);
5631 if (IS_ERR(test_ctx->dev)) {
5632 pr_err(TEST_MODULE_NAME ":device_create err.\n");
5633 return -ENODEV;
5634 }
5635
5636 test_ctx->cdev = cdev_alloc();
5637 if (test_ctx->cdev == NULL) {
5638 pr_err(TEST_MODULE_NAME ":cdev_alloc err.\n");
5639 return -ENODEV;
5640 }
5641 cdev_init(test_ctx->cdev, &test_fops);
5642 test_ctx->cdev->owner = THIS_MODULE;
5643
5644 ret = cdev_add(test_ctx->cdev, test_ctx->dev_num, 1);
5645 if (ret)
5646 pr_err(TEST_MODULE_NAME ":cdev_add err=%d\n", -ret);
5647 else
5648 pr_debug(TEST_MODULE_NAME ":SDIO-AL-Test init OK..\n");
5649
Maya Erez8afd564f2011-08-24 15:57:06 +03005650 platform_driver_register(&sdio_rpc_drv);
5651 platform_driver_register(&sdio_qmi_drv);
5652 platform_driver_register(&sdio_diag_drv);
5653 platform_driver_register(&sdio_smem_drv);
5654 platform_driver_register(&sdio_rmnt_drv);
5655 platform_driver_register(&sdio_dun_drv);
5656 platform_driver_register(&sdio_ciq_drv);
5657
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005658 return ret;
5659}
5660
5661/**
5662 * Module Exit.
5663 */
5664static void __exit test_exit(void)
5665{
5666 int i;
5667
5668 pr_debug(TEST_MODULE_NAME ":test_exit.\n");
5669
5670 test_ctx->exit_flag = true;
5671
5672 msleep(100); /* allow gracefully exit of the worker thread */
5673
5674 cdev_del(test_ctx->cdev);
5675 device_destroy(test_class, test_ctx->dev_num);
5676 unregister_chrdev_region(test_ctx->dev_num, 1);
5677
Maya Erez8afd564f2011-08-24 15:57:06 +03005678 platform_driver_unregister(&sdio_rpc_drv);
5679 platform_driver_unregister(&sdio_qmi_drv);
5680 platform_driver_unregister(&sdio_diag_drv);
5681 platform_driver_unregister(&sdio_smem_drv);
5682 platform_driver_unregister(&sdio_rmnt_drv);
5683 platform_driver_unregister(&sdio_dun_drv);
5684 platform_driver_unregister(&sdio_ciq_drv);
5685
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005686 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
5687 struct test_channel *tch = test_ctx->test_ch_arr[i];
5688 if (!tch)
5689 continue;
5690 kfree(tch->buf);
5691 kfree(tch);
5692 }
5693
5694#ifdef CONFIG_DEBUG_FS
5695 sdio_al_test_debugfs_cleanup();
5696#endif
5697
5698 kfree(test_ctx);
5699
5700 pr_debug(TEST_MODULE_NAME ":test_exit complete.\n");
5701}
5702
5703module_init(test_init);
5704module_exit(test_exit);
5705
5706MODULE_LICENSE("GPL v2");
5707MODULE_DESCRIPTION("SDIO_AL Test");
5708MODULE_AUTHOR("Amir Samuelov <amirs@codeaurora.org>");
5709
5710