blob: b44697e42cf5410e5455d3d13223741d9cd8b998 [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>
31
32#include <sdio_al_private.h>
33#include <linux/debugfs.h>
34
35#include <linux/kthread.h>
36enum lpm_test_msg_type {
Yaniv Gardi3e327762011-07-27 11:11:04 +030037 LPM_NO_MSG, /* 0 */
38 LPM_MSG_SEND, /* 1 */
39 LPM_MSG_REC, /* 2 */
40 LPM_SLEEP, /* 3 */
41 LPM_WAKEUP, /* 4 */
42 LPM_NOTIFY /* 5 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070043};
44
45#define LPM_NO_MSG_NAME "LPM No Event"
46#define LPM_MSG_SEND_NAME "LPM Send Msg Event"
47#define LPM_MSG_REC_NAME "LPM Receive Msg Event"
48#define LPM_SLEEP_NAME "LPM Sleep Event"
49#define LPM_WAKEUP_NAME "LPM Wakeup Event"
50
51/** Module name string */
52#define TEST_MODULE_NAME "sdio_al_test"
53
54#define TEST_SIGNATURE 0x12345678
55#define TEST_CONFIG_SIGNATURE 0xBEEFCAFE
56
57#define MAX_XFER_SIZE (16*1024)
58#define SMEM_MAX_XFER_SIZE 0xBC000
59#define A2_MIN_PACKET_SIZE 5
Maya Erezbde9df82011-08-02 14:40:00 +030060#define DUN_PACKET_SIZE (2*1024)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070061
62#define TEST_DBG(x...) if (test_ctx->runtime_debug) pr_info(x)
63
64#define LPM_TEST_NUM_OF_PACKETS 100
Yaniv Gardi3e327762011-07-27 11:11:04 +030065#define LPM_MAX_OPEN_CHAN_PER_DEV 4
66#define LPM_ARRAY_SIZE (7*LPM_TEST_NUM_OF_PACKETS*LPM_MAX_OPEN_CHAN_PER_DEV)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070067#define SDIO_LPM_TEST "sdio_lpm_test_reading_task"
68#define LPM_TEST_CONFIG_SIGNATURE 0xDEADBABE
Yaniv Gardi3e327762011-07-27 11:11:04 +030069#define LPM_MSG_NAME_SIZE 20
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070070
Maya Erez53508c12011-08-01 14:04:03 +030071#define A2_HEADER_OVERHEAD 8
72
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070073enum sdio_test_case_type {
74 SDIO_TEST_LOOPBACK_HOST,
75 SDIO_TEST_LOOPBACK_CLIENT,
76 SDIO_TEST_LPM_HOST_WAKER,
77 SDIO_TEST_LPM_CLIENT_WAKER,
78 SDIO_TEST_LPM_RANDOM,
79 SDIO_TEST_HOST_SENDER_NO_LP,
Konstantin Dorfman65ac9222011-08-18 16:30:17 +030080 SDIO_TEST_CLOSE_CHANNEL,
Maya Erez53508c12011-08-01 14:04:03 +030081 /* The following tests are not part of the 9k tests and should be
82 * kept last in case new tests are added
83 */
84 SDIO_TEST_PERF,
85 SDIO_TEST_RTT,
Maya Erez8afd564f2011-08-24 15:57:06 +030086 SDIO_TEST_MODEM_RESET,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070087};
88
89struct lpm_task {
90 struct task_struct *lpm_task;
91 const char *task_name;
92};
93
94struct lpm_entry_type {
95 enum lpm_test_msg_type msg_type;
Yaniv Gardi3e327762011-07-27 11:11:04 +030096 char msg_name[LPM_MSG_NAME_SIZE];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070097 u32 counter;
98 u32 current_ms;
Yaniv Gardi3e327762011-07-27 11:11:04 +030099 u32 read_avail_mask;
100 char chan_name[CHANNEL_NAME_SIZE];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700101};
102
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700103struct lpm_msg {
104 u32 signature;
105 u32 counter;
106 u32 reserve1;
107 u32 reserve2;
108};
109
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700110struct test_config_msg {
111 u32 signature;
112 u32 test_case;
113 u32 test_param;
114 u32 num_packets;
115 u32 num_iterations;
116};
117
118struct test_result_msg {
119 u32 signature;
120 u32 is_successful;
121};
122
123struct test_work {
124 struct work_struct work;
125 struct test_channel *test_ch;
126};
127
128enum sdio_channels_ids {
129 SDIO_RPC,
130 SDIO_QMI,
131 SDIO_RMNT,
132 SDIO_DIAG,
133 SDIO_DUN,
134 SDIO_SMEM,
135 SDIO_CIQ,
136 SDIO_MAX_CHANNELS
137};
138
139enum sdio_test_results {
140 TEST_NO_RESULT,
141 TEST_FAILED,
142 TEST_PASSED
143};
144
145enum sdio_lpm_vote_state {
146 SDIO_NO_VOTE,
147 SDIO_VOTE_FOR_SLEEP,
148 SDIO_VOTE_AGAINST_SLEEP
149};
150
Yaniv Gardi3e327762011-07-27 11:11:04 +0300151struct sdio_test_device {
152 int open_channels_counter_to_recv;
153 int open_channels_counter_to_send;
154 struct lpm_entry_type *lpm_arr;
155 int array_size;
156 void *sdio_al_device;
157 spinlock_t lpm_array_lock;
158 unsigned long lpm_array_lock_flags;
159 u32 next_avail_entry_in_array;
160 struct lpm_task lpm_test_task;
161 u32 next_mask_id;
162 u32 read_avail_mask;
163 int modem_result_per_dev;
164 int final_result_per_dev;
165};
166
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700167struct test_channel {
168 struct sdio_channel *ch;
169
170 char name[CHANNEL_NAME_SIZE];
171 int ch_id;
172
Yaniv Gardi3e327762011-07-27 11:11:04 +0300173 struct sdio_test_device *test_device;
174
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700175 u32 *buf;
176 u32 buf_size;
177
178 struct workqueue_struct *workqueue;
179 struct test_work test_work;
180
181 u32 rx_bytes;
182 u32 tx_bytes;
183
184 wait_queue_head_t wait_q;
185 atomic_t rx_notify_count;
186 atomic_t tx_notify_count;
187 atomic_t any_notify_count;
188 atomic_t wakeup_client;
Maya Erez8afd564f2011-08-24 15:57:06 +0300189 atomic_t card_detected_event;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700190
191 int wait_counter;
192
193 int is_used;
194 int test_type;
195 int ch_ready;
196
197 struct test_config_msg config_msg;
198
199 int test_completed;
200 int test_result;
201 struct timer_list timer;
202 int timer_interval_ms;
203
204 struct timer_list timeout_timer;
205 int timeout_ms;
206 void *sdio_al_device;
207 int is_ok_to_sleep;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700208 unsigned int packet_length;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700209 int random_packet_size;
Yaniv Gardi3e327762011-07-27 11:11:04 +0300210 int next_index_in_sent_msg_per_chan;
211 int channel_mask_id;
212 int modem_result_per_chan;
213 int notify_counter_per_chan;
Konstantin Dorfman65ac9222011-08-18 16:30:17 +0300214 int max_burst_size; /* number of writes before close/open */
Maya Erez8afd564f2011-08-24 15:57:06 +0300215 int card_removed;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700216};
217
218struct sdio_al_test_debug {
219 u32 dun_throughput;
220 u32 rmnt_throughput;
221 struct dentry *debug_root;
222 struct dentry *debug_test_result;
223 struct dentry *debug_dun_throughput;
224 struct dentry *debug_rmnt_throughput;
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300225 struct dentry *rpc_sender_test;
226 struct dentry *rpc_qmi_diag_sender_test;
227 struct dentry *smem_test;
228 struct dentry *smem_rpc_test;
229 struct dentry *rmnet_a2_perf_test;
230 struct dentry *dun_a2_perf_test;
231 struct dentry *rmnet_dun_a2_perf_test;
232 struct dentry *rpc_sender_rmnet_a2_perf_test;
233 struct dentry *all_channels_test;
234 struct dentry *host_sender_no_lp_diag_test;
235 struct dentry *host_sender_no_lp_diag_rpc_ciq_test;
236 struct dentry *rmnet_small_packets_test;
237 struct dentry *rmnet_rtt_test;
238 struct dentry *modem_reset_rpc_test;
239 struct dentry *modem_reset_rmnet_test;
240 struct dentry *modem_reset_channels_4bit_dev_test;
241 struct dentry *modem_reset_channels_8bit_dev_test;
242 struct dentry *modem_reset_all_channels_test;
243 struct dentry *open_close_diag_ciq_rpc_test;
244 struct dentry *close_chan_lpm_test;
245 struct dentry *lpm_test_client_wakes_host_test;
246 struct dentry *lpm_test_host_wakes_client_test;
247 struct dentry *lpm_test_random_single_channel_test;
248 struct dentry *lpm_test_random_multi_channel_test;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700249};
250
251struct test_context {
252 dev_t dev_num;
253 struct device *dev;
254 struct cdev *cdev;
Yaniv Gardi3e327762011-07-27 11:11:04 +0300255 int number_of_active_devices;
256 int max_number_of_devices;
257
258 struct sdio_test_device test_dev_arr[MAX_NUM_OF_SDIO_DEVICES];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700259
260 struct test_channel *test_ch;
261
262 struct test_channel *test_ch_arr[SDIO_MAX_CHANNELS];
263
264 long testcase;
265
266 const char *name;
267
268 int exit_flag;
269
270 u32 signature;
271
272 int runtime_debug;
273
274 struct platform_device smem_pdev;
275 struct sdio_smem_client *sdio_smem;
276 int smem_was_init;
277 u8 *smem_buf;
278
279 wait_queue_head_t wait_q;
280 int test_completed;
281 int test_result;
282 struct sdio_al_test_debug debug;
283
284 struct wake_lock wake_lock;
Maya Erezf204e692011-08-12 22:00:13 +0300285
286 unsigned int lpm_pseudo_random_seed;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700287};
288
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300289/* FORWARD DECLARATIONS */
290static int set_params_loopback_9k(struct test_channel *tch);
291static int set_params_smem_test(struct test_channel *tch);
292static int set_params_a2_perf(struct test_channel *tch);
293static int set_params_8k_sender_no_lp(struct test_channel *tch);
294static int set_params_a2_small_pkts(struct test_channel *tch);
295static int set_params_rtt(struct test_channel *tch);
296static int set_params_loopback_9k_close(struct test_channel *tch);
Yaniv Gardib4237782011-08-31 20:06:16 +0300297static int close_channel_lpm_test(int channel_num);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300298static int set_params_lpm_test(struct test_channel *tch,
299 enum sdio_test_case_type test,
300 int timer_interval_ms);
301static void set_pseudo_random_seed(void);
302static int set_params_modem_reset(struct test_channel *tch);
303static int test_start(void);
304
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700305/*
306 * Seed for pseudo random time sleeping in Random LPM test.
307 * If not set, current time in jiffies is used.
308 */
309static unsigned int seed;
310module_param(seed, int, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700311static struct test_context *test_ctx;
312
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300313static void sdio_al_test_initial_dev_and_chan(struct test_context *test_ctx)
314{
315 int i = 0;
316
317 for (i = 0 ; i < MAX_NUM_OF_SDIO_DEVICES ; ++i)
318 test_ctx->test_dev_arr[i].sdio_al_device = NULL;
319
320 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
321 struct test_channel *tch = test_ctx->test_ch_arr[i];
322 if (!tch)
323 continue;
324 tch->is_used = 0;
325 }
326}
327
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700328#ifdef CONFIG_DEBUG_FS
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300329
330static int message_repeat;
331
332static int sdio_al_test_open(struct inode *inode, struct file *file)
333{
334 file->private_data = inode->i_private;
335 message_repeat = 1;
336 return 0;
337}
338
339/* RPC SENDER TEST */
340static ssize_t rpc_sender_test_write(struct file *file,
341 const char __user *buf,
342 size_t count,
343 loff_t *ppos)
344{
345 int ret = 0;
346 int i = 0;
347 int number = -1;
348
349 pr_info(TEST_MODULE_NAME "-- RPC SENDER TEST --\n");
350
351 ret = kstrtoint(buf, 10, &number);
352 if (ret) {
353 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
354 __func__);
355 return count;
356 }
357
358 for (i = 0 ; i < number ; ++i) {
359 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
360 pr_info(TEST_MODULE_NAME " ===============");
361
362 sdio_al_test_initial_dev_and_chan(test_ctx);
363
364 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
365
366 ret = test_start();
367
368 if (ret)
369 break;
370 }
371
372 return count;
373}
374
375static ssize_t rpc_sender_test_read(struct file *file,
376 char __user *buffer,
377 size_t count,
378 loff_t *offset)
379{
380 memset((void *)buffer, 0, count);
381
382 snprintf(buffer, count,
383 "\nRPC_SENDER_TEST\n"
384 "===============\n"
385 "Description:\n"
386 "TBD\n");
387
388 if (message_repeat == 1) {
389 message_repeat = 0;
390 return strnlen(buffer, count);
391 } else {
392 return 0;
393 }
394}
395
396const struct file_operations rpc_sender_test_ops = {
397 .open = sdio_al_test_open,
398 .write = rpc_sender_test_write,
399 .read = rpc_sender_test_read,
400};
401
402/* RPC, QMI & DIAG SENDER TEST */
403static ssize_t rpc_qmi_diag_sender_test_write(struct file *file,
404 const char __user *buf,
405 size_t count,
406 loff_t *ppos)
407{
408 int ret = 0;
409 int i = 0;
410 int number = -1;
411
412 pr_info(TEST_MODULE_NAME "-- RPC, QMI AND DIAG SENDER TEST --\n");
413
414 ret = kstrtoint(buf, 10, &number);
415 if (ret) {
416 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
417 __func__);
418 return count;
419 }
420
421 for (i = 0 ; i < number ; ++i) {
422 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
423 pr_info(TEST_MODULE_NAME " ===============");
424
425 sdio_al_test_initial_dev_and_chan(test_ctx);
426
427 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
428 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_QMI]);
429 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_DIAG]);
430
431 ret = test_start();
432
433 if (ret)
434 break;
435 }
436
437 return count;
438}
439
440static ssize_t rpc_qmi_diag_sender_test_read(struct file *file,
441 char __user
442 *buffer, size_t count,
443 loff_t *offset)
444{
445 memset((void *)buffer, 0, count);
446
447 snprintf(buffer, count,
448 "\nRPC_QMI_DIAG_SENDER_TEST\n"
449 "========================\n"
450 "Description:\n"
451 "TBD\n");
452
453
454 if (message_repeat == 1) {
455 message_repeat = 0;
456 return strnlen(buffer, count);
457 } else {
458 return 0;
459 }
460}
461
462const struct file_operations rpc_qmi_diag_sender_test_ops = {
463 .open = sdio_al_test_open,
464 .write = rpc_qmi_diag_sender_test_write,
465 .read = rpc_qmi_diag_sender_test_read,
466};
467
468/* SMEM TEST */
469static ssize_t smem_test_write(struct file *file,
470 const char __user *buf,
471 size_t count,
472 loff_t *ppos)
473{
474 int ret = 0;
475 int i = 0;
476 int number = -1;
477
478 pr_info(TEST_MODULE_NAME "-- SMEM TEST --\n");
479
480 ret = kstrtoint(buf, 10, &number);
481 if (ret) {
482 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
483 __func__);
484 return count;
485 }
486
487 for (i = 0 ; i < number ; ++i) {
488 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
489 pr_info(TEST_MODULE_NAME " ===============");
490
491 sdio_al_test_initial_dev_and_chan(test_ctx);
492
493 set_params_smem_test(test_ctx->test_ch_arr[SDIO_SMEM]);
494
495 ret = test_start();
496
497 if (ret)
498 break;
499 }
500
501 return count;
502}
503
504static ssize_t smem_test_read(struct file *file,
505 char __user *buffer,
506 size_t count,
507 loff_t *offset)
508{
509 memset((void *)buffer, 0, count);
510
511 snprintf(buffer, count,
512 "\nSMEM_TEST\n"
513 "=========\n"
514 "Description:\n"
515 "TBD\n");
516
517 if (message_repeat == 1) {
518 message_repeat = 0;
519 return strnlen(buffer, count);
520 } else {
521 return 0;
522 }
523}
524
525const struct file_operations smem_test_ops = {
526 .open = sdio_al_test_open,
527 .write = smem_test_write,
528 .read = smem_test_read,
529};
530
531/* SMEM & RPC TEST */
532static ssize_t smem_rpc_test_write(struct file *file,
533 const char __user *buf,
534 size_t count,
535 loff_t *ppos)
536{
537 int ret = 0;
538 int i = 0;
539 int number = -1;
540
541 pr_info(TEST_MODULE_NAME "-- SMEM AND RPC TEST --\n");
542
543 ret = kstrtoint(buf, 10, &number);
544 if (ret) {
545 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
546 __func__);
547 return count;
548 }
549
550 for (i = 0 ; i < number ; ++i) {
551 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
552 pr_info(TEST_MODULE_NAME " ===============");
553
554 sdio_al_test_initial_dev_and_chan(test_ctx);
555
556 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
557 set_params_smem_test(test_ctx->test_ch_arr[SDIO_SMEM]);
558
559 ret = test_start();
560
561 if (ret)
562 break;
563 }
564
565 return count;
566}
567
568static ssize_t smem_rpc_test_read(struct file *file,
569 char __user *buffer,
570 size_t count,
571 loff_t *offset)
572{
573 memset((void *)buffer, 0, count);
574
575 snprintf(buffer, count,
576 "\nSMEM_RPC_TEST\n"
577 "=============\n"
578 "Description:\n"
579 "TBD\n");
580
581 if (message_repeat == 1) {
582 message_repeat = 0;
583 return strnlen(buffer, count);
584 } else {
585 return 0;
586 }
587}
588
589const struct file_operations smem_rpc_test_ops = {
590 .open = sdio_al_test_open,
591 .write = smem_rpc_test_write,
592 .read = smem_rpc_test_read,
593};
594
595/* RMNET A2 PERFORMANCE TEST */
596static ssize_t rmnet_a2_perf_test_write(struct file *file,
597 const char __user *buf,
598 size_t count,
599 loff_t *ppos)
600{
601 int ret = 0;
602 int i = 0;
603 int number = -1;
604
605 pr_info(TEST_MODULE_NAME "-- RMNET A2 PERFORMANCE TEST --\n");
606
607 ret = kstrtoint(buf, 10, &number);
608 if (ret) {
609 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
610 __func__);
611 return count;
612 }
613
614 for (i = 0 ; i < number ; ++i) {
615 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
616 pr_info(TEST_MODULE_NAME " ===============");
617
618 sdio_al_test_initial_dev_and_chan(test_ctx);
619
620 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
621
622 ret = test_start();
623
624 if (ret)
625 break;
626 }
627
628 return count;
629}
630
631static ssize_t rmnet_a2_perf_test_read(struct file *file,
632 char __user *buffer,
633 size_t count,
634 loff_t *offset)
635{
636 memset((void *)buffer, 0, count);
637
638 snprintf(buffer, count,
639 "\nRMNET_A2_PERFORMANCE_TEST\n"
640 "=========================\n"
641 "Description:\n"
642 "TBD\n");
643
644 if (message_repeat == 1) {
645 message_repeat = 0;
646 return strnlen(buffer, count);
647 } else {
648 return 0;
649 }
650}
651
652const struct file_operations rmnet_a2_perf_test_ops = {
653 .open = sdio_al_test_open,
654 .write = rmnet_a2_perf_test_write,
655 .read = rmnet_a2_perf_test_read,
656};
657
658/* DUN A2 PERFORMANCE TEST */
659static ssize_t dun_a2_perf_test_write(struct file *file,
660 const char __user *buf,
661 size_t count,
662 loff_t *ppos)
663{
664 int ret = 0;
665 int i = 0;
666 int number = -1;
667
668 pr_info(TEST_MODULE_NAME "-- DUN A2 PERFORMANCE TEST --\n");
669
670 ret = kstrtoint(buf, 10, &number);
671 if (ret) {
672 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
673 __func__);
674 return count;
675 }
676
677 for (i = 0 ; i < number ; ++i) {
678 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
679 pr_info(TEST_MODULE_NAME " ===============");
680
681 sdio_al_test_initial_dev_and_chan(test_ctx);
682
683 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_DUN]);
684
685 ret = test_start();
686
687 if (ret)
688 break;
689 }
690
691 return count;
692}
693
694static ssize_t dun_a2_perf_test_read(struct file *file,
695 char __user *buffer,
696 size_t count,
697 loff_t *offset)
698{
699 memset((void *)buffer, 0, count);
700
701 snprintf(buffer, count,
702 "\nDUN_A2_PERFORMANCE_TEST\n"
703 "=======================\n"
704 "Description:\n"
705 "TBD\n");
706
707 if (message_repeat == 1) {
708 message_repeat = 0;
709 return strnlen(buffer, count);
710 } else {
711 return 0;
712 }
713}
714
715const struct file_operations dun_a2_perf_test_ops = {
716 .open = sdio_al_test_open,
717 .write = dun_a2_perf_test_write,
718 .read = dun_a2_perf_test_read,
719};
720
721/* RMNET DUN A2 PERFORMANCE TEST */
722static ssize_t rmnet_dun_a2_perf_test_write(struct file *file,
723 const char __user *buf,
724 size_t count,
725 loff_t *ppos)
726{
727 int ret = 0;
728 int i = 0;
729 int number = -1;
730
731 pr_info(TEST_MODULE_NAME "-- RMNET AND DUN A2 PERFORMANCE TEST --\n");
732
733 ret = kstrtoint(buf, 10, &number);
734 if (ret) {
735 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
736 __func__);
737 return count;
738 }
739
740 for (i = 0 ; i < number ; ++i) {
741 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
742 pr_info(TEST_MODULE_NAME " ===============");
743
744 sdio_al_test_initial_dev_and_chan(test_ctx);
745
746 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
747 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_DUN]);
748
749 ret = test_start();
750
751 if (ret)
752 break;
753 }
754
755 return count;
756}
757
758static ssize_t rmnet_dun_a2_perf_test_read(struct file *file,
759 char __user *buffer,
760 size_t count,
761 loff_t *offset)
762{
763 memset((void *)buffer, 0, count);
764
765 snprintf(buffer, count,
766 "\nRMNET_DUN_A2_PERFORMANCE_TEST\n"
767 "=============================\n"
768 "Description:\n"
769 "TBD\n");
770
771 if (message_repeat == 1) {
772 message_repeat = 0;
773 return strnlen(buffer, count);
774 } else {
775 return 0;
776 }
777}
778
779const struct file_operations rmnet_dun_a2_perf_test_ops = {
780 .open = sdio_al_test_open,
781 .write = rmnet_dun_a2_perf_test_write,
782 .read = rmnet_dun_a2_perf_test_read,
783};
784
785/* RPC SENDER & RMNET A2 PERFORMANCE TEST */
786static ssize_t rpc_sender_rmnet_a2_perf_test_write(struct file *file,
787 const char __user *buf,
788 size_t count,
789 loff_t *ppos)
790{
791 int ret = 0;
792 int i = 0;
793 int number = -1;
794
795 pr_info(TEST_MODULE_NAME "--RPC SENDER AND RMNET A2 "
796 "PERFORMANCE --\n");
797
798 ret = kstrtoint(buf, 10, &number);
799 if (ret) {
800 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
801 __func__);
802 return count;
803 }
804
805 for (i = 0 ; i < number ; ++i) {
806 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
807 pr_info(TEST_MODULE_NAME " ===============");
808
809 sdio_al_test_initial_dev_and_chan(test_ctx);
810
811 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
812 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
813
814 ret = test_start();
815
816 if (ret)
817 break;
818 }
819
820 return count;
821}
822
823static ssize_t rpc_sender_rmnet_a2_perf_test_read(struct file *file,
824 char __user *buffer,
825 size_t count,
826 loff_t *offset)
827{
828 memset((void *)buffer, 0, count);
829
830 snprintf(buffer, count,
831 "\nRPC_SENDER_RMNET_A2_PERFORMANCE_TEST\n"
832 "====================================\n"
833 "Description:\n"
834 "TBD\n");
835
836 if (message_repeat == 1) {
837 message_repeat = 0;
838 return strnlen(buffer, count);
839 } else {
840 return 0;
841 }
842}
843
844const struct file_operations rpc_sender_rmnet_a2_perf_test_ops = {
845 .open = sdio_al_test_open,
846 .write = rpc_sender_rmnet_a2_perf_test_write,
847 .read = rpc_sender_rmnet_a2_perf_test_read,
848};
849
850/* ALL CHANNELS TEST */
851static ssize_t all_channels_test_write(struct file *file,
852 const char __user *buf,
853 size_t count,
854 loff_t *ppos)
855{
856 int ret = 0;
857 int i = 0;
858 int number = -1;
859
860 pr_info(TEST_MODULE_NAME "-- ALL THE CHANNELS TEST --\n");
861
862 ret = kstrtoint(buf, 10, &number);
863 if (ret) {
864 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
865 __func__);
866 return count;
867 }
868
869 for (i = 0 ; i < number ; ++i) {
870 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
871 pr_info(TEST_MODULE_NAME " ===============");
872
873 sdio_al_test_initial_dev_and_chan(test_ctx);
874
875 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
876 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_QMI]);
877 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_DIAG]);
878 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
879 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_DUN]);
880 set_params_smem_test(test_ctx->test_ch_arr[SDIO_SMEM]);
881 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_CIQ]);
882
883 ret = test_start();
884
885 if (ret)
886 break;
887 }
888
889 return count;
890}
891
892static ssize_t all_channels_test_read(struct file *file,
893 char __user *buffer,
894 size_t count,
895 loff_t *offset)
896{
897 memset((void *)buffer, 0, count);
898
899 snprintf(buffer, count,
900 "\nALL_CHANNELS_TEST\n"
901 "=================\n"
902 "Description:\n"
903 "TBD\n");
904
905 if (message_repeat == 1) {
906 message_repeat = 0;
907 return strnlen(buffer, count);
908 } else {
909 return 0;
910 }
911}
912
913const struct file_operations all_channels_test_ops = {
914 .open = sdio_al_test_open,
915 .write = all_channels_test_write,
916 .read = all_channels_test_read,
917};
918
919/* HOST SENDER NO LP DIAG TEST */
920static ssize_t host_sender_no_lp_diag_test_write(struct file *file,
921 const char __user *buf,
922 size_t count,
923 loff_t *ppos)
924{
925 int ret = 0;
926 int i = 0;
927 int number = -1;
928
929 pr_info(TEST_MODULE_NAME "-- HOST SENDER NO LP FOR DIAG TEST --");
930
931 ret = kstrtoint(buf, 10, &number);
932 if (ret) {
933 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
934 __func__);
935 return count;
936 }
937
938 for (i = 0 ; i < number ; ++i) {
939 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
940 pr_info(TEST_MODULE_NAME " ===============");
941
942 sdio_al_test_initial_dev_and_chan(test_ctx);
943
944 set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_DIAG]);
945
946 ret = test_start();
947
948 if (ret)
949 break;
950 }
951
952 return count;
953}
954
955static ssize_t host_sender_no_lp_diag_test_read(struct file *file,
956 char __user *buffer,
957 size_t count,
958 loff_t *offset)
959{
960 memset((void *)buffer, 0, count);
961
962 snprintf(buffer, count,
963 "\nHOST_SENDER_NO_LP_DIAG_TEST\n"
964 "===========================\n"
965 "Description:\n"
966 "TBD\n");
967
968 if (message_repeat == 1) {
969 message_repeat = 0;
970 return strnlen(buffer, count);
971 } else {
972 return 0;
973 }
974}
975
976const struct file_operations host_sender_no_lp_diag_test_ops = {
977 .open = sdio_al_test_open,
978 .write = host_sender_no_lp_diag_test_write,
979 .read = host_sender_no_lp_diag_test_read,
980};
981
982/* HOST SENDER NO LP DIAG, RPC, CIQ TEST */
983static ssize_t host_sender_no_lp_diag_rpc_ciq_test_write(
984 struct file *file,
985 const char __user *buf,
986 size_t count,
987 loff_t *ppos)
988{
989 int ret = 0;
990 int i = 0;
991 int number = -1;
992
993 pr_info(TEST_MODULE_NAME "-- HOST SENDER NO LP FOR DIAG, RPC, "
994 "CIQ TEST --");
995
996 ret = kstrtoint(buf, 10, &number);
997 if (ret) {
998 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
999 __func__);
1000 return count;
1001 }
1002
1003 for (i = 0 ; i < number ; ++i) {
1004 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
1005 pr_info(TEST_MODULE_NAME " ===============");
1006
1007 sdio_al_test_initial_dev_and_chan(test_ctx);
1008
1009 set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_DIAG]);
1010 set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_CIQ]);
1011 set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_RPC]);
1012
1013 ret = test_start();
1014
1015 if (ret)
1016 break;
1017 }
1018
1019 return count;
1020}
1021
1022static ssize_t host_sender_no_lp_diag_rpc_ciq_test_read(
1023 struct file *file,
1024 char __user *buffer,
1025 size_t count,
1026 loff_t *offset)
1027{
1028 memset((void *)buffer, 0, count);
1029
1030 snprintf(buffer, count,
1031 "\nHOST_SENDER_NO_LP_DIAG_RPC_CIQ_TEST\n"
1032 "===================================\n"
1033 "Description:\n"
1034 "TBD\n");
1035
1036 if (message_repeat == 1) {
1037 message_repeat = 0;
1038 return strnlen(buffer, count);
1039 } else {
1040 return 0;
1041 }
1042}
1043
1044const struct file_operations host_sender_no_lp_diag_rpc_ciq_test_ops = {
1045 .open = sdio_al_test_open,
1046 .write = host_sender_no_lp_diag_rpc_ciq_test_write,
1047 .read = host_sender_no_lp_diag_rpc_ciq_test_read,
1048};
1049
1050/* RMNET SMALL PACKETS TEST */
1051static ssize_t rmnet_small_packets_test_write(struct file *file,
1052 const char __user *buf,
1053 size_t count,
1054 loff_t *ppos)
1055{
1056 int ret = 0;
1057 int i = 0;
1058 int number = -1;
1059
1060 pr_info(TEST_MODULE_NAME "-- RMNET SMALL PACKETS (5-128) TEST --");
1061
1062 ret = kstrtoint(buf, 10, &number);
1063 if (ret) {
1064 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
1065 __func__);
1066 return count;
1067 }
1068
1069 for (i = 0 ; i < number ; ++i) {
1070 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
1071 pr_info(TEST_MODULE_NAME " ===============");
1072
1073 sdio_al_test_initial_dev_and_chan(test_ctx);
1074
1075 set_params_a2_small_pkts(test_ctx->test_ch_arr[SDIO_RMNT]);
1076
1077 ret = test_start();
1078
1079 if (ret)
1080 break;
1081 }
1082
1083 return count;
1084}
1085
1086static ssize_t rmnet_small_packets_test_read(struct file *file,
1087 char __user *buffer,
1088 size_t count,
1089 loff_t *offset)
1090{
1091 memset((void *)buffer, 0, count);
1092
1093 snprintf(buffer, count,
1094 "\nRMNET_SMALL_PACKETS_TEST\n"
1095 "========================\n"
1096 "Description:\n"
1097 "TBD\n");
1098
1099 if (message_repeat == 1) {
1100 message_repeat = 0;
1101 return strnlen(buffer, count);
1102 } else {
1103 return 0;
1104 }
1105}
1106
1107const struct file_operations rmnet_small_packets_test_ops = {
1108 .open = sdio_al_test_open,
1109 .write = rmnet_small_packets_test_write,
1110 .read = rmnet_small_packets_test_read,
1111};
1112
1113/* RMNET RTT TEST */
1114static ssize_t rmnet_rtt_test_write(struct file *file,
1115 const char __user *buf,
1116 size_t count,
1117 loff_t *ppos)
1118{
1119 int ret = 0;
1120 int i = 0;
1121 int number = -1;
1122
1123 pr_info(TEST_MODULE_NAME "-- RMNET RTT TEST --");
1124
1125 ret = kstrtoint(buf, 10, &number);
1126 if (ret) {
1127 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
1128 __func__);
1129 return count;
1130 }
1131
1132 for (i = 0 ; i < number ; ++i) {
1133 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
1134 pr_info(TEST_MODULE_NAME " ===============");
1135
1136 sdio_al_test_initial_dev_and_chan(test_ctx);
1137
1138 set_params_rtt(test_ctx->test_ch_arr[SDIO_RMNT]);
1139
1140 ret = test_start();
1141
1142 if (ret)
1143 break;
1144 }
1145
1146 return count;
1147}
1148
1149static ssize_t rmnet_rtt_test_read(struct file *file,
1150 char __user *buffer,
1151 size_t count,
1152 loff_t *offset)
1153{
1154 memset((void *)buffer, 0, count);
1155
1156 snprintf(buffer, count,
1157 "\nRMNET_RTT_TEST\n"
1158 "==============\n"
1159 "Description:\n"
1160 "TBD\n");
1161
1162 if (message_repeat == 1) {
1163 message_repeat = 0;
1164 return strnlen(buffer, count);
1165 } else {
1166 return 0;
1167 }
1168}
1169
1170const struct file_operations rmnet_rtt_test_ops = {
1171 .open = sdio_al_test_open,
1172 .write = rmnet_rtt_test_write,
1173 .read = rmnet_rtt_test_read,
1174};
1175
1176/* MODEM RESET RPC TEST */
1177static ssize_t modem_reset_rpc_test_write(struct file *file,
1178 const char __user *buf,
1179 size_t count,
1180 loff_t *ppos)
1181{
1182 int ret = 0;
1183 int i = 0;
1184 int number = -1;
1185
1186 pr_info(TEST_MODULE_NAME "-- MODEM RESET - RPC CHANNEL TEST --");
1187
1188 ret = kstrtoint(buf, 10, &number);
1189 if (ret) {
1190 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
1191 __func__);
1192 return count;
1193 }
1194
1195 for (i = 0 ; i < number ; ++i) {
1196 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
1197 pr_info(TEST_MODULE_NAME " ===============");
1198
1199 sdio_al_test_initial_dev_and_chan(test_ctx);
1200
1201 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RPC]);
1202
1203 ret = test_start();
1204
1205 if (ret)
1206 break;
1207 }
1208
1209 return count;
1210}
1211
1212static ssize_t modem_reset_rpc_test_read(struct file *file,
1213 char __user *buffer,
1214 size_t count,
1215 loff_t *offset)
1216{
1217 memset((void *)buffer, 0, count);
1218
1219 snprintf(buffer, count,
1220 "\nMODEM_RESET_RPC_TEST\n"
1221 "====================\n"
1222 "Description:\n"
1223 "TBD\n");
1224
1225 if (message_repeat == 1) {
1226 message_repeat = 0;
1227 return strnlen(buffer, count);
1228 } else {
1229 return 0;
1230 }
1231}
1232
1233const struct file_operations modem_reset_rpc_test_ops = {
1234 .open = sdio_al_test_open,
1235 .write = modem_reset_rpc_test_write,
1236 .read = modem_reset_rpc_test_read,
1237};
1238
1239/* MODEM RESET RMNET TEST */
1240static ssize_t modem_reset_rmnet_test_write(struct file *file,
1241 const char __user *buf,
1242 size_t count,
1243 loff_t *ppos)
1244{
1245 int ret = 0;
1246 int i = 0;
1247 int number = -1;
1248
1249 pr_info(TEST_MODULE_NAME "-- MODEM RESET - RMNT CHANNEL TEST --");
1250
1251 ret = kstrtoint(buf, 10, &number);
1252 if (ret) {
1253 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
1254 __func__);
1255 return count;
1256 }
1257
1258 for (i = 0 ; i < number ; ++i) {
1259 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
1260 pr_info(TEST_MODULE_NAME " ===============");
1261
1262 sdio_al_test_initial_dev_and_chan(test_ctx);
1263
1264 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]);
1265
1266 ret = test_start();
1267
1268 if (ret)
1269 break;
1270 }
1271
1272 return count;
1273}
1274
1275static ssize_t modem_reset_rmnet_test_read(struct file *file,
1276 char __user *buffer,
1277 size_t count,
1278 loff_t *offset)
1279{
1280 memset((void *)buffer, 0, count);
1281
1282 snprintf(buffer, count,
1283 "\nMODEM_RESET_RMNET_TEST\n"
1284 "======================\n"
1285 "Description:\n"
1286 "TBD\n");
1287
1288 if (message_repeat == 1) {
1289 message_repeat = 0;
1290 return strnlen(buffer, count);
1291 } else {
1292 return 0;
1293 }
1294}
1295
1296const struct file_operations modem_reset_rmnet_test_ops = {
1297 .open = sdio_al_test_open,
1298 .write = modem_reset_rmnet_test_write,
1299 .read = modem_reset_rmnet_test_read,
1300};
1301
1302/* MODEM RESET - CHANNELS IN 4BIT DEVICE TEST */
1303static ssize_t modem_reset_channels_4bit_dev_test_write(
1304 struct file *file,
1305 const char __user *buf,
1306 size_t count,
1307 loff_t *ppos)
1308{
1309 int ret = 0;
1310 int i = 0;
1311 int number = -1;
1312
1313 pr_info(TEST_MODULE_NAME "-- MODEM RESET - ALL CHANNELS IN "
1314 "4BIT DEVICE TEST --");
1315
1316 ret = kstrtoint(buf, 10, &number);
1317 if (ret) {
1318 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
1319 __func__);
1320 return count;
1321 }
1322
1323 for (i = 0 ; i < number ; ++i) {
1324 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
1325 pr_info(TEST_MODULE_NAME " ===============");
1326
1327 sdio_al_test_initial_dev_and_chan(test_ctx);
1328
1329 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RPC]);
1330 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_QMI]);
1331 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DIAG]);
1332
1333 ret = test_start();
1334
1335 if (ret)
1336 break;
1337 }
1338
1339 return count;
1340}
1341
1342static ssize_t modem_reset_channels_4bit_dev_test_read(
1343 struct file *file,
1344 char __user *buffer,
1345 size_t count,
1346 loff_t *offset)
1347{
1348 memset((void *)buffer, 0, count);
1349
1350 snprintf(buffer, count,
1351 "\nMODEM_RESET_CHANNELS_4BIT_DEV_TEST\n"
1352 "==================================\n"
1353 "Description:\n"
1354 "TBD\n");
1355
1356 if (message_repeat == 1) {
1357 message_repeat = 0;
1358 return strnlen(buffer, count);
1359 } else {
1360 return 0;
1361 }
1362}
1363
1364const struct file_operations modem_reset_channels_4bit_dev_test_ops = {
1365 .open = sdio_al_test_open,
1366 .write = modem_reset_channels_4bit_dev_test_write,
1367 .read = modem_reset_channels_4bit_dev_test_read,
1368};
1369
1370/* MODEM RESET - CHANNELS IN 8BIT DEVICE TEST */
1371static ssize_t modem_reset_channels_8bit_dev_test_write(
1372 struct file *file,
1373 const char __user *buf,
1374 size_t count,
1375 loff_t *ppos)
1376{
1377 int ret = 0;
1378 int i = 0;
1379 int number = -1;
1380
1381 pr_info(TEST_MODULE_NAME "-- MODEM RESET - ALL CHANNELS IN "
1382 "8BIT DEVICE TEST --");
1383
1384 ret = kstrtoint(buf, 10, &number);
1385 if (ret) {
1386 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
1387 __func__);
1388 return count;
1389 }
1390
1391 for (i = 0 ; i < number ; ++i) {
1392 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
1393 pr_info(TEST_MODULE_NAME " ===============");
1394
1395 sdio_al_test_initial_dev_and_chan(test_ctx);
1396
1397 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]);
1398 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DUN]);
1399 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_CIQ]);
1400
1401 ret = test_start();
1402
1403 if (ret)
1404 break;
1405 }
1406
1407 return count;
1408}
1409
1410static ssize_t modem_reset_channels_8bit_dev_test_read(
1411 struct file *file,
1412 char __user *buffer,
1413 size_t count,
1414 loff_t *offset)
1415{
1416 memset((void *)buffer, 0, count);
1417
1418 snprintf(buffer, count,
1419 "\nMODEM_RESET_CHANNELS_8BIT_DEV_TEST\n"
1420 "==================================\n"
1421 "Description:\n"
1422 "TBD\n");
1423
1424 if (message_repeat == 1) {
1425 message_repeat = 0;
1426 return strnlen(buffer, count);
1427 } else {
1428 return 0;
1429 }
1430}
1431
1432const struct file_operations modem_reset_channels_8bit_dev_test_ops = {
1433 .open = sdio_al_test_open,
1434 .write = modem_reset_channels_8bit_dev_test_write,
1435 .read = modem_reset_channels_8bit_dev_test_read,
1436};
1437
1438/* MODEM RESET - ALL CHANNELS TEST */
1439static ssize_t modem_reset_all_channels_test_write(struct file *file,
1440 const char __user *buf,
1441 size_t count,
1442 loff_t *ppos)
1443{
1444 int ret = 0;
1445 int i = 0;
1446 int number = -1;
1447
1448 pr_info(TEST_MODULE_NAME "-- MODEM RESET - ALL CHANNELS TEST --");
1449
1450 ret = kstrtoint(buf, 10, &number);
1451 if (ret) {
1452 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
1453 __func__);
1454 return count;
1455 }
1456
1457 for (i = 0 ; i < number ; ++i) {
1458 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
1459 pr_info(TEST_MODULE_NAME " ===============");
1460
1461 sdio_al_test_initial_dev_and_chan(test_ctx);
1462
1463 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RPC]);
1464 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_QMI]);
1465 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DIAG]);
1466 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]);
1467 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DUN]);
1468 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_CIQ]);
1469
1470 ret = test_start();
1471
1472 if (ret)
1473 break;
1474 }
1475
1476 return count;
1477}
1478
1479static ssize_t modem_reset_all_channels_test_read(struct file *file,
1480 char __user *buffer,
1481 size_t count,
1482 loff_t *offset)
1483{
1484 memset((void *)buffer, 0, count);
1485
1486 snprintf(buffer, count,
1487 "\nMODEM_RESET_ALL_CHANNELS_TEST\n"
1488 "=============================\n"
1489 "Description:\n"
1490 "TBD\n");
1491
1492 if (message_repeat == 1) {
1493 message_repeat = 0;
1494 return strnlen(buffer, count);
1495 } else {
1496 return 0;
1497 }
1498}
1499
1500const struct file_operations modem_reset_all_channels_test_ops = {
1501 .open = sdio_al_test_open,
1502 .write = modem_reset_all_channels_test_write,
1503 .read = modem_reset_all_channels_test_read,
1504};
1505
1506/* HOST SENDER WITH OPEN/CLOSE FOR DIAG, CIQ & RPC TEST */
1507static ssize_t open_close_diag_ciq_rpc_test_write(struct file *file,
1508 const char __user *buf,
1509 size_t count,
1510 loff_t *ppos)
1511{
1512 int ret = 0;
1513 struct test_channel **ch_arr = test_ctx->test_ch_arr;
1514 int i = 0;
1515 int number = -1;
1516
1517 pr_info(TEST_MODULE_NAME "-- HOST SENDER WITH OPEN/CLOSE FOR "
1518 "DIAG, CIQ AND RPC TEST --");
1519
1520 ret = kstrtoint(buf, 10, &number);
1521 if (ret) {
1522 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
1523 __func__);
1524 return count;
1525 }
1526
1527 for (i = 0 ; i < number ; ++i) {
1528 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
1529 pr_info(TEST_MODULE_NAME " ===============");
1530
1531 sdio_al_test_initial_dev_and_chan(test_ctx);
1532
1533 set_params_loopback_9k_close(ch_arr[SDIO_DIAG]);
1534 set_params_loopback_9k_close(ch_arr[SDIO_CIQ]);
1535 set_params_loopback_9k_close(ch_arr[SDIO_RPC]);
1536
1537 ret = test_start();
1538
1539 if (ret)
1540 break;
1541
1542 pr_info(TEST_MODULE_NAME " -- correctness test for"
1543 "DIAG, CIQ and RPC ");
1544 set_params_loopback_9k(ch_arr[SDIO_DIAG]);
1545 set_params_loopback_9k(ch_arr[SDIO_CIQ]);
1546 set_params_loopback_9k(ch_arr[SDIO_RPC]);
1547
1548 ret = test_start();
1549
1550 if (ret)
1551 break;
1552 }
1553
1554 return count;
1555}
1556
1557static ssize_t open_close_diag_ciq_rpc_test_read(struct file *file,
1558 char __user *buffer,
1559 size_t count,
1560 loff_t *offset)
1561{
1562 memset((void *)buffer, 0, count);
1563
1564 snprintf(buffer, count,
1565 "\nOPEN_CLOSE_DIAG_CIQ_RPC_TEST\n"
1566 "============================\n"
1567 "Description:\n"
1568 "TBD\n");
1569
1570 if (message_repeat == 1) {
1571 message_repeat = 0;
1572 return strnlen(buffer, count);
1573 } else {
1574 return 0;
1575 }
1576}
1577
1578const struct file_operations open_close_diag_ciq_rpc_test_ops = {
1579 .open = sdio_al_test_open,
1580 .write = open_close_diag_ciq_rpc_test_write,
1581 .read = open_close_diag_ciq_rpc_test_read,
1582};
1583
1584/* CLOSE CHANNEL & LPM TEST HOST WAKES THE CLIENT TEST */
1585static ssize_t close_chan_lpm_test_write(struct file *file,
1586 const char __user *buf,
1587 size_t count,
1588 loff_t *ppos)
1589{
1590 int ret = 0;
1591 int i = 0;
Yaniv Gardib4237782011-08-31 20:06:16 +03001592 int channel_num = 0;
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001593 int number = -1;
1594
1595 pr_info(TEST_MODULE_NAME "-- CLOSE CHANNEL & LPM TEST "
1596 "HOST WAKES THE CLIENT TEST --\n");
1597
1598 ret = kstrtoint(buf, 10, &number);
1599 if (ret) {
1600 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
1601 __func__);
1602 return count;
1603 }
1604
1605 for (i = 0 ; i < number ; ++i) {
1606 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
1607 pr_info(TEST_MODULE_NAME " ===============");
1608
1609 sdio_al_test_initial_dev_and_chan(test_ctx);
1610
Yaniv Gardib4237782011-08-31 20:06:16 +03001611 for (channel_num = 0 ; channel_num < SDIO_MAX_CHANNELS ;
1612 channel_num++) {
1613 if (channel_num == SDIO_SMEM ||
1614 channel_num == SDIO_RMNT ||
1615 channel_num == SDIO_DUN)
1616 continue;
1617
1618 ret = close_channel_lpm_test(channel_num);
1619
1620 if (ret)
1621 break;
1622
1623 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
1624 SDIO_TEST_LPM_HOST_WAKER, 120);
1625
1626 ret = test_start();
1627
1628 if (ret)
1629 break;
1630 }
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001631
1632 if (ret) {
1633 pr_err(TEST_MODULE_NAME " -- Close channel & LPM Test "
1634 "FAILED: %d --\n", ret);
1635 } else {
1636 pr_err(TEST_MODULE_NAME " -- Close channel & LPM Test "
1637 "PASSED\n");
1638 }
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001639 }
1640
1641 return count;
1642}
1643
1644static ssize_t close_chan_lpm_test_read(struct file *file,
1645 char __user *buffer,
1646 size_t count,
1647 loff_t *offset)
1648{
1649 memset((void *)buffer, 0, count);
1650
1651 snprintf(buffer, count,
1652 "\nCLOSE_CHAN_LPM_TEST\n"
1653 "===================\n"
1654 "Description:\n"
1655 "TBD\n");
1656
1657 if (message_repeat == 1) {
1658 message_repeat = 0;
1659 return strnlen(buffer, count);
1660 } else {
1661 return 0;
1662 }
1663}
1664
1665const struct file_operations close_chan_lpm_test_ops = {
1666 .open = sdio_al_test_open,
1667 .write = close_chan_lpm_test_write,
1668 .read = close_chan_lpm_test_read,
1669};
1670
1671/* LPM TEST FOR DEVICE 1. CLIENT WAKES THE HOST TEST */
1672static ssize_t lpm_test_client_wakes_host_test_write(struct file *file,
1673 const char __user *buf,
1674 size_t count,
1675 loff_t *ppos)
1676{
1677 int ret = 0;
1678 int i = 0;
1679 int number = -1;
1680
1681 pr_info(TEST_MODULE_NAME "-- LPM TEST FOR DEVICE 1. CLIENT "
1682 "WAKES THE HOST TEST --\n");
1683
1684 ret = kstrtoint(buf, 10, &number);
1685 if (ret) {
1686 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
1687 __func__);
1688 return count;
1689 }
1690
1691 for (i = 0 ; i < number ; ++i) {
1692 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
1693 pr_info(TEST_MODULE_NAME " ===============");
1694
1695 sdio_al_test_initial_dev_and_chan(test_ctx);
1696
1697 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
1698 SDIO_TEST_LPM_CLIENT_WAKER, 90);
1699
1700 ret = test_start();
1701
1702 if (ret)
1703 break;
1704 }
1705
1706 return count;
1707}
1708
1709static ssize_t lpm_test_client_wakes_host_test_read(struct file *file,
1710 char __user *buffer,
1711 size_t count,
1712 loff_t *offset)
1713{
1714 memset((void *)buffer, 0, count);
1715
1716 snprintf(buffer, count,
1717 "\nLPM_TEST_CLIENT_WAKES_HOST_TEST\n"
1718 "===============================\n"
1719 "Description:\n"
1720 "In this test, the HOST is going into LPM mode,\n"
1721 "and the CLIENT is responsible to send it a message\n"
1722 "in order to wake it up\n\n"
1723 "END OF DESCRIPTION\n");
1724
1725 if (message_repeat == 1) {
1726 message_repeat = 0;
1727 return strnlen(buffer, count);
1728 } else {
1729 return 0;
1730 }
1731}
1732
1733const struct file_operations lpm_test_client_wakes_host_test_ops = {
1734 .open = sdio_al_test_open,
1735 .write = lpm_test_client_wakes_host_test_write,
1736 .read = lpm_test_client_wakes_host_test_read,
1737};
1738
1739/* LPM TEST FOR DEVICE 1. HOST WAKES THE CLIENT TEST */
1740static ssize_t lpm_test_host_wakes_client_test_write(struct file *file,
1741 const char __user *buf,
1742 size_t count,
1743 loff_t *ppos)
1744{
1745 int ret = 0;
1746 int i = 0;
1747 int number = -1;
1748
1749 pr_info(TEST_MODULE_NAME "-- LPM TEST FOR DEVICE 1. HOST "
1750 "WAKES THE CLIENT TEST --\n");
1751
1752 ret = kstrtoint(buf, 10, &number);
1753 if (ret) {
1754 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
1755 __func__);
1756 return count;
1757 }
1758
1759 for (i = 0 ; i < number ; ++i) {
1760 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
1761 pr_info(TEST_MODULE_NAME " ===============");
1762
1763 sdio_al_test_initial_dev_and_chan(test_ctx);
1764
1765 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
1766 SDIO_TEST_LPM_HOST_WAKER, 120);
1767
1768 ret = test_start();
1769
1770 if (ret)
1771 break;
1772 }
1773
1774 return count;
1775}
1776
1777static ssize_t lpm_test_host_wakes_client_test_read(struct file *file,
1778 char __user *buffer,
1779 size_t count,
1780 loff_t *offset)
1781{
1782 memset((void *)buffer, 0, count);
1783
1784 snprintf(buffer, count,
1785 "\nLPM_TEST_HOST_WAKES_CLIENT_TEST\n"
1786 "===============================\n"
1787 "Description:\n"
1788 "In this test, the CLIENT goes into LPM mode, and the\n"
1789 "HOST is responsible to send it a message\n"
1790 "in order to wake it up\n\n"
1791 "END OF DESCRIPTION\n");
1792
1793 if (message_repeat == 1) {
1794 message_repeat = 0;
1795 return strnlen(buffer, count);
1796 } else {
1797 return 0;
1798 }
1799}
1800
1801const struct file_operations lpm_test_host_wakes_client_test_ops = {
1802 .open = sdio_al_test_open,
1803 .write = lpm_test_host_wakes_client_test_write,
1804 .read = lpm_test_host_wakes_client_test_read,
1805};
1806
1807/* LPM TEST RANDOM, SINGLE CHANNEL TEST */
1808static ssize_t lpm_test_random_single_channel_test_write(
1809 struct file *file,
1810 const char __user *buf,
1811 size_t count,
1812 loff_t *ppos)
1813{
1814 int ret = 0;
1815 int i = 0;
1816 int number = -1;
1817
1818 pr_info(TEST_MODULE_NAME "-- LPM TEST RANDOM SINGLE "
1819 "CHANNEL TEST --\n");
1820
1821 ret = kstrtoint(buf, 10, &number);
1822 if (ret) {
1823 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
1824 __func__);
1825 return count;
1826 }
1827
1828 for (i = 0 ; i < number ; ++i) {
1829 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
1830 pr_info(TEST_MODULE_NAME " ===============");
1831
1832 sdio_al_test_initial_dev_and_chan(test_ctx);
1833
1834 set_pseudo_random_seed();
1835 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
1836 SDIO_TEST_LPM_RANDOM, 0);
1837
1838 ret = test_start();
1839
1840 if (ret)
1841 break;
1842 }
1843
1844 return count;
1845}
1846
1847static ssize_t lpm_test_random_single_channel_test_read(
1848 struct file *file,
1849 char __user *buffer,
1850 size_t count,
1851 loff_t *offset)
1852{
1853 memset((void *)buffer, 0, count);
1854
1855 snprintf(buffer, count,
1856 "\nLPM_TEST_RANDOM_SINGLE_CHANNEL_TEST\n"
1857 "===================================\n"
1858 "Description:\n"
1859 "In this test, the HOST and CLIENT "
1860 "send messages to each other,\n"
1861 "random in time, over RPC channel only.\n"
1862 "All events are being recorded, and later on,\n"
1863 "they are being analysed by the HOST and by the CLIENT\n,"
1864 "in order to check if the LPM mechanism worked properly,\n"
1865 "meaning:"
1866 " When all the relevant conditions are met, a device should:\n"
1867 "1. Go to sleep\n"
1868 "2. Wake up\n"
1869 "3. Stay awake\n\n"
1870 "END OF DESCRIPTION\n");
1871
1872 if (message_repeat == 1) {
1873 message_repeat = 0;
1874 return strnlen(buffer, count);
1875 } else {
1876 return 0;
1877 }
1878}
1879
1880const struct file_operations lpm_test_random_single_channel_test_ops = {
1881 .open = sdio_al_test_open,
1882 .write = lpm_test_random_single_channel_test_write,
1883 .read = lpm_test_random_single_channel_test_read,
1884};
1885
1886/* LPM TEST RANDOM, MULTI CHANNEL TEST */
1887static ssize_t lpm_test_random_multi_channel_test_write(
1888 struct file *file,
1889 const char __user *buf,
1890 size_t count,
1891 loff_t *ppos)
1892{
1893 int ret = 0;
1894 int i = 0;
1895 int number = -1;
1896
1897 pr_info(TEST_MODULE_NAME "-- LPM TEST RANDOM MULTI CHANNEL TEST --\n");
1898
1899 ret = kstrtoint(buf, 10, &number);
1900 if (ret) {
1901 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
1902 __func__);
1903 return count;
1904 }
1905
1906 for (i = 0 ; i < number ; ++i) {
1907 pr_info(TEST_MODULE_NAME " - Cycle # %d\n", i+1);
1908 pr_info(TEST_MODULE_NAME " ===============");
1909
1910 sdio_al_test_initial_dev_and_chan(test_ctx);
1911
1912 set_pseudo_random_seed();
1913
1914 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
1915 SDIO_TEST_LPM_RANDOM, 0);
1916 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_CIQ],
1917 SDIO_TEST_LPM_RANDOM, 0);
1918 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_DIAG],
1919 SDIO_TEST_LPM_RANDOM, 0);
1920 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_QMI],
1921 SDIO_TEST_LPM_RANDOM, 0);
1922
1923 ret = test_start();
1924
1925 if (ret)
1926 break;
1927 }
1928
1929 return count;
1930}
1931
1932static ssize_t lpm_test_random_multi_channel_test_read(
1933 struct file *file,
1934 char __user *buffer,
1935 size_t count,
1936 loff_t *offset)
1937{
1938 memset((void *)buffer, 0, count);
1939
1940 snprintf(buffer, count,
1941 "\nLPM_TEST_RANDOM_MULTI_CHANNEL_TEST\n"
1942 "==================================\n"
1943 "Description:\n"
1944 "In this test, the HOST and CLIENT "
1945 "send messages to each other,\n"
1946 "random in time, over RPC, QMI, DIAG AND CIQ channels\n"
1947 "(i.e, on both SDIO devices).\n"
1948 "All events are being recorded, and later on,\n"
1949 "they are being analysed by the HOST and by the CLIENT,\n"
1950 "in order to check if the LPM mechanism worked properly,\n"
1951 "meaning:"
1952 " When all the relevant conditions are met, a device should:\n"
1953 "1. Go to sleep\n"
1954 "2. Wake up\n"
1955 "3. Stay awake\n\n"
1956 "END OF DESCRIPTION\n");
1957
1958 if (message_repeat == 1) {
1959 message_repeat = 0;
1960 return strnlen(buffer, count);
1961 } else {
1962 return 0;
1963 }
1964}
1965
1966const struct file_operations lpm_test_random_multi_channel_test_ops = {
1967 .open = sdio_al_test_open,
1968 .write = lpm_test_random_multi_channel_test_write,
1969 .read = lpm_test_random_multi_channel_test_read,
1970};
1971
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001972static int sdio_al_test_debugfs_init(void)
1973{
1974 test_ctx->debug.debug_root = debugfs_create_dir("sdio_al_test",
1975 NULL);
1976 if (!test_ctx->debug.debug_root)
1977 return -ENOENT;
1978
1979 test_ctx->debug.debug_test_result = debugfs_create_u32(
1980 "test_result",
1981 S_IRUGO | S_IWUGO,
1982 test_ctx->debug.debug_root,
1983 &test_ctx->test_result);
1984
1985 test_ctx->debug.debug_dun_throughput = debugfs_create_u32(
1986 "dun_throughput",
1987 S_IRUGO | S_IWUGO,
1988 test_ctx->debug.debug_root,
1989 &test_ctx->debug.dun_throughput);
1990
1991 test_ctx->debug.debug_rmnt_throughput = debugfs_create_u32(
1992 "rmnt_throughput",
1993 S_IRUGO | S_IWUGO,
1994 test_ctx->debug.debug_root,
1995 &test_ctx->debug.rmnt_throughput);
1996
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001997 test_ctx->debug.rpc_sender_test =
1998 debugfs_create_file("10_rpc_sender_test",
1999 S_IRUGO | S_IWUGO,
2000 test_ctx->debug.debug_root,
2001 NULL,
2002 &rpc_sender_test_ops);
2003
2004 test_ctx->debug.rpc_qmi_diag_sender_test =
2005 debugfs_create_file("20_rpc_qmi_diag_sender_test",
2006 S_IRUGO | S_IWUGO,
2007 test_ctx->debug.debug_root,
2008 NULL,
2009 &rpc_qmi_diag_sender_test_ops);
2010
2011 test_ctx->debug.smem_test =
2012 debugfs_create_file("40_smem_test",
2013 S_IRUGO | S_IWUGO,
2014 test_ctx->debug.debug_root,
2015 NULL,
2016 &smem_test_ops);
2017
2018 test_ctx->debug.smem_rpc_test =
2019 debugfs_create_file("50_smem_rpc_test",
2020 S_IRUGO | S_IWUGO,
2021 test_ctx->debug.debug_root,
2022 NULL,
2023 &smem_rpc_test_ops);
2024
2025 test_ctx->debug.rmnet_a2_perf_test =
2026 debugfs_create_file("60_rmnet_a2_perf_test",
2027 S_IRUGO | S_IWUGO,
2028 test_ctx->debug.debug_root,
2029 NULL,
2030 &rmnet_a2_perf_test_ops);
2031
2032 test_ctx->debug.dun_a2_perf_test =
2033 debugfs_create_file("70_dun_a2_perf_test",
2034 S_IRUGO | S_IWUGO,
2035 test_ctx->debug.debug_root,
2036 NULL,
2037 &dun_a2_perf_test_ops);
2038
2039 test_ctx->debug.rmnet_dun_a2_perf_test =
2040 debugfs_create_file("80_rmnet_dun_a2_perf_test",
2041 S_IRUGO | S_IWUGO,
2042 test_ctx->debug.debug_root,
2043 NULL,
2044 &rmnet_dun_a2_perf_test_ops);
2045
2046 test_ctx->debug.rpc_sender_rmnet_a2_perf_test =
2047 debugfs_create_file("90_rpc_sender_rmnet_a2_perf_test",
2048 S_IRUGO | S_IWUGO,
2049 test_ctx->debug.debug_root,
2050 NULL,
2051 &rpc_sender_rmnet_a2_perf_test_ops);
2052
2053 test_ctx->debug.all_channels_test =
2054 debugfs_create_file("100_all_channels_test",
2055 S_IRUGO | S_IWUGO,
2056 test_ctx->debug.debug_root,
2057 NULL,
2058 &all_channels_test_ops);
2059
2060 test_ctx->debug.host_sender_no_lp_diag_test =
2061 debugfs_create_file("160_host_sender_no_lp_diag_test",
2062 S_IRUGO | S_IWUGO,
2063 test_ctx->debug.debug_root,
2064 NULL,
2065 &host_sender_no_lp_diag_test_ops);
2066
2067 test_ctx->debug.host_sender_no_lp_diag_rpc_ciq_test =
2068 debugfs_create_file("170_host_sender_no_lp_diag_rpc_ciq_test",
2069 S_IRUGO | S_IWUGO,
2070 test_ctx->debug.debug_root,
2071 NULL,
2072 &host_sender_no_lp_diag_rpc_ciq_test_ops);
2073
2074 test_ctx->debug.rmnet_small_packets_test =
2075 debugfs_create_file("180_rmnet_small_packets_test",
2076 S_IRUGO | S_IWUGO,
2077 test_ctx->debug.debug_root,
2078 NULL,
2079 &rmnet_small_packets_test_ops);
2080
2081 test_ctx->debug.rmnet_rtt_test =
2082 debugfs_create_file("190_rmnet_rtt_test",
2083 S_IRUGO | S_IWUGO,
2084 test_ctx->debug.debug_root,
2085 NULL,
2086 &rmnet_rtt_test_ops);
2087
2088 test_ctx->debug.modem_reset_rpc_test =
2089 debugfs_create_file("220_modem_reset_rpc_test",
2090 S_IRUGO | S_IWUGO,
2091 test_ctx->debug.debug_root,
2092 NULL,
2093 &modem_reset_rpc_test_ops);
2094
2095 test_ctx->debug.modem_reset_rmnet_test =
2096 debugfs_create_file("230_modem_reset_rmnet_test",
2097 S_IRUGO | S_IWUGO,
2098 test_ctx->debug.debug_root,
2099 NULL,
2100 &modem_reset_rmnet_test_ops);
2101
2102 test_ctx->debug.modem_reset_channels_4bit_dev_test =
2103 debugfs_create_file("240_modem_reset_channels_4bit_dev_test",
2104 S_IRUGO | S_IWUGO,
2105 test_ctx->debug.debug_root,
2106 NULL,
2107 &modem_reset_channels_4bit_dev_test_ops);
2108
2109 test_ctx->debug.modem_reset_channels_8bit_dev_test =
2110 debugfs_create_file("250_modem_reset_channels_8bit_dev_test",
2111 S_IRUGO | S_IWUGO,
2112 test_ctx->debug.debug_root,
2113 NULL,
2114 &modem_reset_channels_8bit_dev_test_ops);
2115
2116 test_ctx->debug.modem_reset_all_channels_test =
2117 debugfs_create_file("260_modem_reset_all_channels_test",
2118 S_IRUGO | S_IWUGO,
2119 test_ctx->debug.debug_root,
2120 NULL,
2121 &modem_reset_all_channels_test_ops);
2122
2123 test_ctx->debug.open_close_diag_ciq_rpc_test =
2124 debugfs_create_file("270_open_close_diag_ciq_rpc_test",
2125 S_IRUGO | S_IWUGO,
2126 test_ctx->debug.debug_root,
2127 NULL,
2128 &open_close_diag_ciq_rpc_test_ops);
2129
2130 test_ctx->debug.close_chan_lpm_test =
2131 debugfs_create_file("280_close_chan_lpm_test",
2132 S_IRUGO | S_IWUGO,
2133 test_ctx->debug.debug_root,
2134 NULL,
2135 &close_chan_lpm_test_ops);
2136
2137 test_ctx->debug.lpm_test_client_wakes_host_test =
2138 debugfs_create_file("600_lpm_test_client_wakes_host_test",
2139 S_IRUGO | S_IWUGO,
2140 test_ctx->debug.debug_root,
2141 NULL,
2142 &lpm_test_client_wakes_host_test_ops);
2143
2144 test_ctx->debug.lpm_test_host_wakes_client_test =
2145 debugfs_create_file("610_lpm_test_host_wakes_client_test",
2146 S_IRUGO | S_IWUGO,
2147 test_ctx->debug.debug_root,
2148 NULL,
2149 &lpm_test_host_wakes_client_test_ops);
2150
2151 test_ctx->debug.lpm_test_random_single_channel_test =
2152 debugfs_create_file("620_lpm_test_random_single_channel_test",
2153 S_IRUGO | S_IWUGO,
2154 test_ctx->debug.debug_root,
2155 NULL,
2156 &lpm_test_random_single_channel_test_ops);
2157
2158 test_ctx->debug.lpm_test_random_multi_channel_test =
2159 debugfs_create_file("630_lpm_test_random_multi_channel_test",
2160 S_IRUGO | S_IWUGO,
2161 test_ctx->debug.debug_root,
2162 NULL,
2163 &lpm_test_random_multi_channel_test_ops);
2164
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002165 if ((!test_ctx->debug.debug_dun_throughput) &&
2166 (!test_ctx->debug.debug_rmnt_throughput)) {
2167 debugfs_remove_recursive(test_ctx->debug.debug_root);
2168 test_ctx->debug.debug_root = NULL;
2169 return -ENOENT;
2170 }
2171 return 0;
2172}
2173
2174static void sdio_al_test_debugfs_cleanup(void)
2175{
2176 debugfs_remove(test_ctx->debug.debug_dun_throughput);
2177 debugfs_remove(test_ctx->debug.debug_rmnt_throughput);
2178 debugfs_remove(test_ctx->debug.debug_root);
2179}
2180#endif
2181
2182static int channel_name_to_id(char *name)
2183{
2184 pr_info(TEST_MODULE_NAME "%s: channel name %s\n",
2185 __func__, name);
2186
Maya Erez8afd564f2011-08-24 15:57:06 +03002187 if (!strncmp(name, "SDIO_RPC_TEST",
2188 strnlen("SDIO_RPC_TEST", CHANNEL_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002189 return SDIO_RPC;
Maya Erez8afd564f2011-08-24 15:57:06 +03002190 else if (!strncmp(name, "SDIO_QMI_TEST",
2191 strnlen("SDIO_QMI_TEST", TEST_CH_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002192 return SDIO_QMI;
Maya Erez8afd564f2011-08-24 15:57:06 +03002193 else if (!strncmp(name, "SDIO_RMNT_TEST",
2194 strnlen("SDIO_RMNT_TEST", TEST_CH_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002195 return SDIO_RMNT;
Maya Erez8afd564f2011-08-24 15:57:06 +03002196 else if (!strncmp(name, "SDIO_DIAG_TEST",
2197 strnlen("SDIO_DIAG", TEST_CH_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002198 return SDIO_DIAG;
Maya Erez8afd564f2011-08-24 15:57:06 +03002199 else if (!strncmp(name, "SDIO_DUN_TEST",
2200 strnlen("SDIO_DUN_TEST", TEST_CH_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002201 return SDIO_DUN;
Maya Erez8afd564f2011-08-24 15:57:06 +03002202 else if (!strncmp(name, "SDIO_SMEM_TEST",
2203 strnlen("SDIO_SMEM_TEST", TEST_CH_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002204 return SDIO_SMEM;
Maya Erez8afd564f2011-08-24 15:57:06 +03002205 else if (!strncmp(name, "SDIO_CIQ_TEST",
2206 strnlen("SDIO_CIQ_TEST", TEST_CH_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002207 return SDIO_CIQ;
2208 else
2209 return SDIO_MAX_CHANNELS;
2210
2211 return SDIO_MAX_CHANNELS;
2212}
2213
2214/**
2215 * Config message
2216 */
2217
2218static void send_config_msg(struct test_channel *test_ch)
2219{
2220 int ret = 0 ;
2221 u32 write_avail = 0;
2222 int size = sizeof(test_ch->config_msg);
2223
2224 pr_debug(TEST_MODULE_NAME "%s\n", __func__);
2225
2226 memcpy(test_ch->buf, (void *)&test_ch->config_msg, size);
2227
2228 if (test_ctx->exit_flag) {
2229 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
2230 return;
2231 }
2232
2233 pr_info(TEST_MODULE_NAME ":Sending the config message.\n");
2234
2235 /* wait for data ready event */
2236 write_avail = sdio_write_avail(test_ch->ch);
2237 pr_debug(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
2238 if (write_avail < size) {
2239 wait_event(test_ch->wait_q,
2240 atomic_read(&test_ch->tx_notify_count));
2241 atomic_dec(&test_ch->tx_notify_count);
2242 }
2243
2244 write_avail = sdio_write_avail(test_ch->ch);
2245 pr_debug(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
2246 if (write_avail < size) {
2247 pr_info(TEST_MODULE_NAME ":not enough write avail.\n");
2248 return;
2249 }
2250
2251 ret = sdio_write(test_ch->ch, test_ch->buf, size);
2252 if (ret)
2253 pr_err(TEST_MODULE_NAME ":%s sdio_write err=%d.\n",
2254 __func__, -ret);
2255 else
2256 pr_info(TEST_MODULE_NAME ":%s sent config_msg successfully.\n",
2257 __func__);
2258}
2259
2260/**
2261 * Loopback Test
2262 */
2263static void loopback_test(struct test_channel *test_ch)
2264{
2265 int ret = 0 ;
2266 u32 read_avail = 0;
2267 u32 write_avail = 0;
2268
2269 while (1) {
2270
2271 if (test_ctx->exit_flag) {
2272 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
2273 return;
2274 }
2275
2276 TEST_DBG(TEST_MODULE_NAME "--LOOPBACK WAIT FOR EVENT--.\n");
2277 /* wait for data ready event */
2278 wait_event(test_ch->wait_q,
2279 atomic_read(&test_ch->rx_notify_count));
2280 atomic_dec(&test_ch->rx_notify_count);
2281
2282 read_avail = sdio_read_avail(test_ch->ch);
2283 if (read_avail == 0)
2284 continue;
2285
2286
2287 write_avail = sdio_write_avail(test_ch->ch);
2288 if (write_avail < read_avail) {
2289 pr_info(TEST_MODULE_NAME
2290 ":not enough write avail.\n");
2291 continue;
2292 }
2293
2294 ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
2295 if (ret) {
2296 pr_info(TEST_MODULE_NAME
2297 ":worker, sdio_read err=%d.\n", -ret);
2298 continue;
2299 }
2300 test_ch->rx_bytes += read_avail;
2301
2302 TEST_DBG(TEST_MODULE_NAME ":worker total rx bytes = 0x%x.\n",
2303 test_ch->rx_bytes);
2304
2305
2306 ret = sdio_write(test_ch->ch,
2307 test_ch->buf, read_avail);
2308 if (ret) {
2309 pr_info(TEST_MODULE_NAME
2310 ":loopback sdio_write err=%d.\n",
2311 -ret);
2312 continue;
2313 }
2314 test_ch->tx_bytes += read_avail;
2315
2316 TEST_DBG(TEST_MODULE_NAME
2317 ":loopback total tx bytes = 0x%x.\n",
2318 test_ch->tx_bytes);
2319 } /* end of while */
2320}
2321
2322/**
2323 * Check if all tests completed
2324 */
2325static void check_test_completion(void)
2326{
2327 int i;
2328
2329 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
2330 struct test_channel *tch = test_ctx->test_ch_arr[i];
2331
2332 if ((!tch) || (!tch->is_used) || (!tch->ch_ready))
2333 continue;
2334 if (!tch->test_completed) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002335 pr_info(TEST_MODULE_NAME ": %s - Channel %s test is "
2336 "not completed", __func__, tch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002337 return;
2338 }
2339 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03002340 pr_info(TEST_MODULE_NAME ": %s - Test is completed", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002341 test_ctx->test_completed = 1;
2342 wake_up(&test_ctx->wait_q);
2343}
2344
2345static int pseudo_random_seed(unsigned int *seed_number)
2346{
2347 if (!seed_number)
2348 return 0;
2349
2350 *seed_number = (unsigned int)(((unsigned long)*seed_number *
2351 (unsigned long)1103515367) + 35757);
Maya Erezf204e692011-08-12 22:00:13 +03002352 return (int)((*seed_number / (64*1024)) % 500);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002353}
2354
Yaniv Gardi3e327762011-07-27 11:11:04 +03002355/* this function must be locked before accessing it */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002356static void lpm_test_update_entry(struct test_channel *tch,
2357 enum lpm_test_msg_type msg_type,
Yaniv Gardi3e327762011-07-27 11:11:04 +03002358 char *msg_name,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002359 int counter)
2360{
2361 u32 index = 0;
2362 static int print_full = 1;
Yaniv Gardi3e327762011-07-27 11:11:04 +03002363 struct sdio_test_device *test_device;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002364
2365 if (!tch) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002366 pr_err(TEST_MODULE_NAME ": %s - NULL test channel\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002367 return;
2368 }
2369
Yaniv Gardi3e327762011-07-27 11:11:04 +03002370 test_device = tch->test_device;
2371
2372 if (!test_device) {
2373 pr_err(TEST_MODULE_NAME ": %s - NULL test device\n", __func__);
2374 return;
2375 }
2376
Maya Erez8afd564f2011-08-24 15:57:06 +03002377 if (!test_device->lpm_arr) {
2378 pr_err(TEST_MODULE_NAME ": %s - NULL lpm_arr\n", __func__);
2379 return;
2380 }
2381
Yaniv Gardi3e327762011-07-27 11:11:04 +03002382 if (test_device->next_avail_entry_in_array >=
2383 test_device->array_size) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002384 pr_err(TEST_MODULE_NAME ": %s - lpm array is full",
2385 __func__);
Yaniv Gardi3e327762011-07-27 11:11:04 +03002386
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002387 if (print_full) {
2388 print_hex_dump(KERN_INFO, TEST_MODULE_NAME ": lpm_arr:",
2389 0, 32, 2,
Yaniv Gardi3e327762011-07-27 11:11:04 +03002390 (void *)test_device->lpm_arr,
2391 sizeof(test_device->lpm_arr), false);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002392 print_full = 0;
2393 }
2394 return;
2395 }
2396
Yaniv Gardi3e327762011-07-27 11:11:04 +03002397 index = test_device->next_avail_entry_in_array;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002398 if ((msg_type == LPM_MSG_SEND) || (msg_type == LPM_MSG_REC))
Yaniv Gardi3e327762011-07-27 11:11:04 +03002399 test_device->lpm_arr[index].counter = counter;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002400 else
Yaniv Gardi3e327762011-07-27 11:11:04 +03002401 test_device->lpm_arr[index].counter = 0;
2402
2403 test_device->lpm_arr[index].msg_type = msg_type;
2404 memcpy(test_device->lpm_arr[index].msg_name, msg_name,
2405 LPM_MSG_NAME_SIZE);
2406 test_device->lpm_arr[index].current_ms =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002407 jiffies_to_msecs(get_jiffies_64());
2408
Yaniv Gardi3e327762011-07-27 11:11:04 +03002409 test_device->lpm_arr[index].read_avail_mask =
2410 test_device->read_avail_mask;
2411
2412 if ((msg_type == LPM_SLEEP) || (msg_type == LPM_WAKEUP))
2413 memcpy(test_device->lpm_arr[index].chan_name, "DEVICE ",
2414 CHANNEL_NAME_SIZE);
2415 else
2416 memcpy(test_device->lpm_arr[index].chan_name, tch->name,
2417 CHANNEL_NAME_SIZE);
2418
2419 test_device->next_avail_entry_in_array++;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002420}
2421
2422static int wait_for_result_msg(struct test_channel *test_ch)
2423{
2424 u32 read_avail = 0;
2425 int ret = 0;
2426
Yaniv Gardi3e327762011-07-27 11:11:04 +03002427 pr_info(TEST_MODULE_NAME ": %s - START, channel %s\n",
2428 __func__, test_ch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002429
2430 while (1) {
2431 read_avail = sdio_read_avail(test_ch->ch);
2432
2433 if (read_avail == 0) {
2434 pr_info(TEST_MODULE_NAME
2435 ": read_avail is 0 for chan %s\n",
2436 test_ch->name);
2437 wait_event(test_ch->wait_q,
2438 atomic_read(&test_ch->rx_notify_count));
2439 atomic_dec(&test_ch->rx_notify_count);
2440 continue;
2441 }
2442
2443 memset(test_ch->buf, 0x00, test_ch->buf_size);
2444
2445 ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
2446 if (ret) {
2447 pr_info(TEST_MODULE_NAME ": sdio_read for chan"
2448 "%s failed, err=%d.\n",
2449 test_ch->name, -ret);
2450 goto exit_err;
2451 }
2452
2453 if (test_ch->buf[0] != TEST_CONFIG_SIGNATURE) {
2454 pr_info(TEST_MODULE_NAME ": Not a test_result "
2455 "signature. expected 0x%x. received 0x%x "
2456 "for chan %s\n",
2457 TEST_CONFIG_SIGNATURE,
2458 test_ch->buf[0],
2459 test_ch->name);
2460 continue;
2461 } else {
2462 pr_info(TEST_MODULE_NAME ": Signature is "
2463 "TEST_CONFIG_SIGNATURE as expected\n");
2464 break;
2465 }
2466 }
2467
2468 return test_ch->buf[1];
2469
2470exit_err:
2471 return 0;
2472}
2473
Yaniv Gardi3e327762011-07-27 11:11:04 +03002474static int check_random_lpm_test_array(struct sdio_test_device *test_dev)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002475{
2476 int i = 0, j = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002477 unsigned int delta_ms = 0;
2478 int arr_ind = 0;
Yaniv Gardi3e327762011-07-27 11:11:04 +03002479 int ret = 1;
2480 int notify_counter = 0;
2481 int sleep_counter = 0;
2482 int wakeup_counter = 0;
2483 int lpm_activity_counter = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002484
Yaniv Gardi3e327762011-07-27 11:11:04 +03002485 if (!test_dev) {
2486 pr_err(TEST_MODULE_NAME ": %s - NULL test device\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002487 return -ENODEV;
2488 }
2489
Yaniv Gardi3e327762011-07-27 11:11:04 +03002490 for (i = 0 ; i < test_dev->next_avail_entry_in_array ; ++i) {
2491 if (i == 0)
2492 pr_err(TEST_MODULE_NAME ": index %4d, chan=%2s, "
2493 "code=%1d=%4s, msg#%1d, ms from before=-1, "
2494 "read_mask=0x%d, ms=%2u",
2495 i,
2496 test_dev->lpm_arr[i].chan_name,
2497 test_dev->lpm_arr[i].msg_type,
2498 test_dev->lpm_arr[i].msg_name,
2499 test_dev->lpm_arr[i].counter,
2500 test_dev->lpm_arr[i].read_avail_mask,
2501 test_dev->lpm_arr[i].current_ms);
2502 else
2503 pr_err(TEST_MODULE_NAME ": index "
2504 "%4d, %2s, code=%1d=%4s, msg#%1d, ms from "
2505 "before=%2u, read_mask=0x%d, ms=%2u",
2506 i,
2507 test_dev->lpm_arr[i].chan_name,
2508 test_dev->lpm_arr[i].msg_type,
2509 test_dev->lpm_arr[i].msg_name,
2510 test_dev->lpm_arr[i].counter,
2511 test_dev->lpm_arr[i].current_ms -
2512 test_dev->lpm_arr[i-1].current_ms,
2513 test_dev->lpm_arr[i].read_avail_mask,
2514 test_dev->lpm_arr[i].current_ms);
2515 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002516
Yaniv Gardi3e327762011-07-27 11:11:04 +03002517 for (i = 0; i < test_dev->next_avail_entry_in_array; i++) {
2518 notify_counter = 0;
2519 sleep_counter = 0;
2520 wakeup_counter = 0;
2521
2522 if ((test_dev->lpm_arr[i].msg_type == LPM_MSG_SEND) ||
2523 (test_dev->lpm_arr[i].msg_type == LPM_MSG_REC)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002524 /* find the next message in the array */
Yaniv Gardi3e327762011-07-27 11:11:04 +03002525 arr_ind = test_dev->next_avail_entry_in_array;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002526 for (j = i+1; j < arr_ind; j++) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002527 if ((test_dev->lpm_arr[j].msg_type ==
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002528 LPM_MSG_SEND) ||
Yaniv Gardi3e327762011-07-27 11:11:04 +03002529 (test_dev->lpm_arr[j].msg_type ==
2530 LPM_MSG_REC) ||
2531 (test_dev->lpm_arr[j].msg_type ==
2532 LPM_NOTIFY))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002533 break;
Yaniv Gardi3e327762011-07-27 11:11:04 +03002534 if (test_dev->lpm_arr[j].msg_type ==
2535 LPM_SLEEP)
2536 sleep_counter++;
2537 if (test_dev->lpm_arr[j].msg_type ==
2538 LPM_WAKEUP)
2539 wakeup_counter++;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002540 }
2541 if (j == arr_ind) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002542 ret = 1;
2543 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002544 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03002545
2546 delta_ms = test_dev->lpm_arr[j].current_ms -
2547 test_dev->lpm_arr[i].current_ms;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002548 if (delta_ms < 30) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002549 if ((sleep_counter == 0)
2550 && (wakeup_counter == 0)) {
2551 continue;
2552 } else {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002553 pr_err(TEST_MODULE_NAME "%s: lpm "
2554 "activity while delta is less "
Yaniv Gardi3e327762011-07-27 11:11:04 +03002555 "than 30, i=%d, j=%d, "
2556 "sleep_counter=%d, "
2557 "wakeup_counter=%d",
2558 __func__, i, j,
2559 sleep_counter, wakeup_counter);
2560 ret = 0;
2561 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002562 }
2563 } else {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002564 if ((delta_ms > 90) &&
2565 (test_dev->lpm_arr[i].
2566 read_avail_mask == 0)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002567 if (j != i+3) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002568 pr_err(TEST_MODULE_NAME
2569 "%s: unexpected "
2570 "lpm activity "
2571 "while delta is "
2572 "bigger than "
2573 "90, i=%d, "
2574 "j=%d, "
2575 "notify_counter"
2576 "=%d",
2577 __func__, i, j,
2578 notify_counter);
2579 ret = 0;
2580 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002581 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03002582 lpm_activity_counter++;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002583 }
2584 }
2585 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002586 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03002587
2588 pr_info(TEST_MODULE_NAME ": %s - lpm_activity_counter=%d",
2589 __func__, lpm_activity_counter);
2590
2591 return ret;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002592}
2593
2594static int lpm_test_main_task(void *ptr)
2595{
2596 u32 read_avail = 0;
2597 int last_msg_index = 0;
2598 struct test_channel *test_ch = (struct test_channel *)ptr;
Yaniv Gardi3e327762011-07-27 11:11:04 +03002599 struct sdio_test_device *test_dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002600 struct lpm_msg lpm_msg;
2601 int ret = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002602 int host_result = 0;
2603
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002604 if (!test_ch) {
2605 pr_err(TEST_MODULE_NAME ": %s - NULL channel\n", __func__);
2606 return -ENODEV;
2607 }
2608
Yaniv Gardi3e327762011-07-27 11:11:04 +03002609 pr_err(TEST_MODULE_NAME ": %s - STARTED. channel %s\n",
2610 __func__, test_ch->name);
2611
2612 test_dev = test_ch->test_device;
2613
2614 if (!test_dev) {
2615 pr_err(TEST_MODULE_NAME ": %s - NULL Test Device\n", __func__);
2616 return -ENODEV;
2617 }
2618
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002619 while (last_msg_index < test_ch->config_msg.num_packets - 1) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002620
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002621 TEST_DBG(TEST_MODULE_NAME ": %s - "
2622 "IN LOOP last_msg_index=%d\n",
2623 __func__, last_msg_index);
2624
2625 read_avail = sdio_read_avail(test_ch->ch);
2626 if (read_avail == 0) {
2627 TEST_DBG(TEST_MODULE_NAME
2628 ":read_avail 0 for chan %s, "
2629 "wait for event\n",
2630 test_ch->name);
2631 wait_event(test_ch->wait_q,
2632 atomic_read(&test_ch->rx_notify_count));
2633 atomic_dec(&test_ch->rx_notify_count);
2634
2635 read_avail = sdio_read_avail(test_ch->ch);
2636 if (read_avail == 0) {
2637 pr_err(TEST_MODULE_NAME
2638 ":read_avail size %d for chan %s not as"
2639 " expected\n",
2640 read_avail, test_ch->name);
2641 continue;
2642 }
2643 }
2644
2645 memset(test_ch->buf, 0x00, sizeof(test_ch->buf));
2646
2647 ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
2648 if (ret) {
2649 pr_info(TEST_MODULE_NAME ":sdio_read for chan %s"
Yaniv Gardi3e327762011-07-27 11:11:04 +03002650 " err=%d.\n", test_ch->name, -ret);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002651 goto exit_err;
2652 }
2653
2654 memcpy((void *)&lpm_msg, test_ch->buf, sizeof(lpm_msg));
2655
Yaniv Gardi3e327762011-07-27 11:11:04 +03002656 /*
2657 * when reading from channel, we want to turn off the bit
2658 * mask that implies that there is pending data on that channel
2659 */
2660 if (test_ch->test_device != NULL) {
2661 spin_lock_irqsave(&test_dev->lpm_array_lock,
2662 test_dev->lpm_array_lock_flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002663
Yaniv Gardi3e327762011-07-27 11:11:04 +03002664 test_ch->notify_counter_per_chan--;
2665
2666 /*
2667 * if the channel has no pending data, turn off the
2668 * pending data bit mask of the channel
2669 */
2670 if (test_ch->notify_counter_per_chan == 0) {
2671 test_ch->test_device->read_avail_mask =
2672 test_ch->test_device->read_avail_mask &
2673 ~test_ch->channel_mask_id;
2674 }
2675
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002676 last_msg_index = lpm_msg.counter;
Yaniv Gardi3e327762011-07-27 11:11:04 +03002677 lpm_test_update_entry(test_ch,
2678 LPM_MSG_REC,
2679 "RECEIVE",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002680 last_msg_index);
Yaniv Gardi3e327762011-07-27 11:11:04 +03002681
2682 spin_unlock_irqrestore(&test_dev->lpm_array_lock,
2683 test_dev->lpm_array_lock_flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002684 }
2685 }
2686
Yaniv Gardi3e327762011-07-27 11:11:04 +03002687 pr_info(TEST_MODULE_NAME ":%s: Finished to recieve all (%d) "
2688 "packets from the modem %s. Waiting for result_msg",
2689 __func__, test_ch->config_msg.num_packets, test_ch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002690
2691 /* Wait for the resault message from the modem */
Yaniv Gardi3e327762011-07-27 11:11:04 +03002692 test_ch->modem_result_per_chan = wait_for_result_msg(test_ch);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002693
Yaniv Gardi3e327762011-07-27 11:11:04 +03002694 /*
2695 * the DEVICE modem result is a failure if one of the channels on
2696 * that device, got modem_result = 0. this is why we bitwise "AND" each
2697 * time another channel completes its task
2698 */
2699 test_dev->modem_result_per_dev &= test_ch->modem_result_per_chan;
2700
2701 /*
2702 * when reading from channel, we want to turn off the bit
2703 * mask that implies that there is pending data on that channel
2704 */
2705 spin_lock_irqsave(&test_dev->lpm_array_lock,
2706 test_dev->lpm_array_lock_flags);
2707
2708 test_dev->open_channels_counter_to_recv--;
2709
2710 /* turning off the read_avail bit of the channel */
2711 test_ch->test_device->read_avail_mask =
2712 test_ch->test_device->read_avail_mask &
2713 ~test_ch->channel_mask_id;
2714
2715 spin_unlock_irqrestore(&test_dev->lpm_array_lock,
2716 test_dev->lpm_array_lock_flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002717
2718 /* Wait for all the packets to be sent to the modem */
2719 while (1) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002720 spin_lock_irqsave(&test_dev->lpm_array_lock,
2721 test_dev->lpm_array_lock_flags);
2722
2723 if (test_ch->next_index_in_sent_msg_per_chan >=
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002724 test_ch->config_msg.num_packets - 1) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002725
2726 spin_unlock_irqrestore(&test_dev->lpm_array_lock,
2727 test_dev->lpm_array_lock_flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002728 break;
2729 } else {
2730 pr_info(TEST_MODULE_NAME ":%s: Didn't finished to send "
Yaniv Gardi3e327762011-07-27 11:11:04 +03002731 "all packets, "
2732 "next_index_in_sent_msg_per_chan = %d ",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002733 __func__,
Yaniv Gardi3e327762011-07-27 11:11:04 +03002734 test_ch->next_index_in_sent_msg_per_chan);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002735 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03002736 spin_unlock_irqrestore(&test_dev->lpm_array_lock,
2737 test_dev->lpm_array_lock_flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002738 msleep(60);
2739 }
2740
Yaniv Gardi3e327762011-07-27 11:11:04 +03002741 if (test_dev->open_channels_counter_to_recv != 0 ||
2742 test_dev->open_channels_counter_to_send != 0) {
2743 test_ch->test_completed = 1;
2744 test_ch->next_index_in_sent_msg_per_chan = 0;
2745 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002746 } else {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002747 test_ctx->number_of_active_devices--;
2748 sdio_al_unregister_lpm_cb(test_ch->sdio_al_device);
2749
2750 if (test_ch->test_type == SDIO_TEST_LPM_RANDOM)
2751 host_result = check_random_lpm_test_array(test_dev);
2752
2753 pr_info(TEST_MODULE_NAME ": %s - host_result=%d. "
2754 "device_modem_result=%d",
2755 __func__, host_result, test_dev->modem_result_per_dev);
2756
2757 test_ch->test_completed = 1;
2758 if (test_dev->modem_result_per_dev && host_result) {
2759 pr_info(TEST_MODULE_NAME ": %s - Random LPM "
2760 "TEST_PASSED for device %d of %d\n",
2761 __func__,
2762 (test_ctx->max_number_of_devices-
2763 test_ctx->number_of_active_devices),
2764 test_ctx->max_number_of_devices);
2765 test_dev->final_result_per_dev = 1; /* PASSED */
2766 } else {
2767 pr_info(TEST_MODULE_NAME ": %s - Random LPM "
2768 "TEST_FAILED for device %d of %d\n",
2769 __func__,
2770 (test_ctx->max_number_of_devices-
2771 test_ctx->number_of_active_devices),
2772 test_ctx->max_number_of_devices);
2773 test_dev->final_result_per_dev = 0; /* FAILED */
2774 }
2775
2776 test_dev->next_avail_entry_in_array = 0;
2777 test_ch->next_index_in_sent_msg_per_chan = 0;
2778
2779 check_test_completion();
2780
2781 kfree(test_ch->test_device->lpm_arr);
2782
2783 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002784 }
2785
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002786exit_err:
2787 pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
2788 test_ch->name);
2789 test_ch->test_completed = 1;
Yaniv Gardi3e327762011-07-27 11:11:04 +03002790 test_dev->open_channels_counter_to_recv--;
2791 test_dev->next_avail_entry_in_array = 0;
2792 test_ch->next_index_in_sent_msg_per_chan = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002793 test_ch->test_result = TEST_FAILED;
2794 check_test_completion();
2795 return -ENODEV;
2796}
2797
2798static int lpm_test_create_read_thread(struct test_channel *test_ch)
2799{
Yaniv Gardi3e327762011-07-27 11:11:04 +03002800 struct sdio_test_device *test_dev;
2801
2802 pr_info(TEST_MODULE_NAME ": %s - STARTED channel %s\n",
2803 __func__, test_ch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002804
2805 if (!test_ch) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002806 pr_err(TEST_MODULE_NAME ": %s - NULL test channel\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002807 return -ENODEV;
2808 }
2809
Yaniv Gardi3e327762011-07-27 11:11:04 +03002810 test_dev = test_ch->test_device;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002811
Yaniv Gardi3e327762011-07-27 11:11:04 +03002812 if (!test_dev) {
2813 pr_err(TEST_MODULE_NAME ": %s - NULL test device\n", __func__);
2814 return -ENODEV;
2815 }
2816
2817 test_dev->lpm_test_task.task_name = SDIO_LPM_TEST;
2818
2819 test_dev->lpm_test_task.lpm_task =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002820 kthread_create(lpm_test_main_task,
2821 (void *)(test_ch),
Yaniv Gardi3e327762011-07-27 11:11:04 +03002822 test_dev->lpm_test_task.task_name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002823
Yaniv Gardi3e327762011-07-27 11:11:04 +03002824 if (IS_ERR(test_dev->lpm_test_task.lpm_task)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002825 pr_err(TEST_MODULE_NAME ": %s - kthread_create() failed\n",
2826 __func__);
2827 return -ENOMEM;
2828 }
2829
Yaniv Gardi3e327762011-07-27 11:11:04 +03002830 wake_up_process(test_dev->lpm_test_task.lpm_task);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002831
2832 return 0;
2833}
2834
2835static void lpm_continuous_rand_test(struct test_channel *test_ch)
2836{
2837 unsigned int local_ms = 0;
2838 int ret = 0;
2839 unsigned int write_avail = 0;
Yaniv Gardi3e327762011-07-27 11:11:04 +03002840 struct sdio_test_device *test_dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002841
2842 pr_info(MODULE_NAME ": %s - STARTED\n", __func__);
2843
2844 if (!test_ch) {
2845 pr_err(TEST_MODULE_NAME ": %s - NULL channel\n", __func__);
2846 return;
2847 }
2848
Yaniv Gardi3e327762011-07-27 11:11:04 +03002849 test_dev = test_ch->test_device;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002850
Yaniv Gardi3e327762011-07-27 11:11:04 +03002851 if (!test_dev) {
2852 pr_err(TEST_MODULE_NAME ": %s - NULL Test Device\n", __func__);
2853 return;
2854 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002855
2856 ret = lpm_test_create_read_thread(test_ch);
2857 if (ret != 0) {
2858 pr_err(TEST_MODULE_NAME ": %s - failed to create lpm reading "
2859 "thread", __func__);
2860 }
2861
Yaniv Gardi3e327762011-07-27 11:11:04 +03002862 while (test_ch->next_index_in_sent_msg_per_chan <=
2863 test_ch->config_msg.num_packets - 1) {
2864
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002865 struct lpm_msg msg;
2866 u32 ret = 0;
2867
Yaniv Gardi3e327762011-07-27 11:11:04 +03002868 /* sleeping period is dependent on number of open channels */
Maya Erezf204e692011-08-12 22:00:13 +03002869 test_ch->config_msg.test_param =
2870 test_ctx->lpm_pseudo_random_seed;
Yaniv Gardi3e327762011-07-27 11:11:04 +03002871
2872 local_ms = test_dev->open_channels_counter_to_send *
Maya Erezf204e692011-08-12 22:00:13 +03002873 test_ctx->lpm_pseudo_random_seed;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002874 TEST_DBG(TEST_MODULE_NAME ":%s: SLEEPING for %d ms",
2875 __func__, local_ms);
2876 msleep(local_ms);
2877
Yaniv Gardi3e327762011-07-27 11:11:04 +03002878 msg.counter = test_ch->next_index_in_sent_msg_per_chan;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002879 msg.signature = LPM_TEST_CONFIG_SIGNATURE;
2880 msg.reserve1 = 0;
2881 msg.reserve2 = 0;
2882
2883 /* wait for data ready event */
2884 write_avail = sdio_write_avail(test_ch->ch);
2885 pr_debug(TEST_MODULE_NAME ": %s: write_avail=%d\n",
2886 __func__, write_avail);
2887 if (write_avail < sizeof(msg)) {
2888 wait_event(test_ch->wait_q,
2889 atomic_read(&test_ch->tx_notify_count));
2890 atomic_dec(&test_ch->tx_notify_count);
2891 }
2892
2893 write_avail = sdio_write_avail(test_ch->ch);
2894 if (write_avail < sizeof(msg)) {
2895 pr_info(TEST_MODULE_NAME ": %s: not enough write "
2896 "avail.\n", __func__);
2897 break;
2898 }
2899
2900 ret = sdio_write(test_ch->ch, (u32 *)&msg, sizeof(msg));
2901 if (ret)
2902 pr_err(TEST_MODULE_NAME ":%s: sdio_write err=%d.\n",
2903 __func__, -ret);
2904
Yaniv Gardi3e327762011-07-27 11:11:04 +03002905 TEST_DBG(TEST_MODULE_NAME ": %s: for chan %s, write, "
2906 "msg # %d\n",
2907 __func__,
2908 test_ch->name,
2909 test_ch->next_index_in_sent_msg_per_chan);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002910
Yaniv Gardi3e327762011-07-27 11:11:04 +03002911 if (test_ch->test_type == SDIO_TEST_LPM_RANDOM) {
2912 spin_lock_irqsave(&test_dev->lpm_array_lock,
2913 test_dev->lpm_array_lock_flags);
2914 lpm_test_update_entry(test_ch, LPM_MSG_SEND,
2915 "SEND ",
2916 test_ch->
2917 next_index_in_sent_msg_per_chan);
2918
2919 test_ch->next_index_in_sent_msg_per_chan++;
2920
2921 spin_unlock_irqrestore(&test_dev->lpm_array_lock,
2922 test_dev->lpm_array_lock_flags);
2923 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002924 }
2925
Yaniv Gardi3e327762011-07-27 11:11:04 +03002926 spin_lock_irqsave(&test_dev->lpm_array_lock,
2927 test_dev->lpm_array_lock_flags);
2928 test_dev->open_channels_counter_to_send--;
2929 spin_unlock_irqrestore(&test_dev->lpm_array_lock,
2930 test_dev->lpm_array_lock_flags);
2931
2932 pr_info(TEST_MODULE_NAME ": %s: - Finished to send all (%d) "
2933 "packets to the modem on channel %s",
2934 __func__, test_ch->config_msg.num_packets, test_ch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002935
2936 return;
2937}
2938
2939static void lpm_test(struct test_channel *test_ch)
2940{
Yaniv Gardi3e327762011-07-27 11:11:04 +03002941 pr_info(TEST_MODULE_NAME ": %s - START channel %s\n", __func__,
2942 test_ch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002943
2944 if (!test_ch) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002945 pr_err(TEST_MODULE_NAME ": %s - NULL test channel\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002946 return;
2947 }
2948
Yaniv Gardi3e327762011-07-27 11:11:04 +03002949 test_ch->modem_result_per_chan = wait_for_result_msg(test_ch);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002950 pr_debug(TEST_MODULE_NAME ": %s - delete the timeout timer\n",
2951 __func__);
2952 del_timer_sync(&test_ch->timeout_timer);
2953
Yaniv Gardi3e327762011-07-27 11:11:04 +03002954 if (test_ch->modem_result_per_chan == 0) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002955 pr_err(TEST_MODULE_NAME ": LPM TEST - Client didn't sleep. "
2956 "Result Msg - is_successful=%d\n", test_ch->buf[1]);
2957 goto exit_err;
2958 } else {
2959 pr_info(TEST_MODULE_NAME ": %s -"
2960 "LPM 9K WAS SLEEPING - PASS\n", __func__);
2961 if (test_ch->test_result == TEST_PASSED) {
2962 pr_info(TEST_MODULE_NAME ": LPM TEST_PASSED\n");
2963 test_ch->test_completed = 1;
2964 check_test_completion();
2965 } else {
2966 pr_err(TEST_MODULE_NAME ": LPM TEST - Host didn't "
2967 "sleep. Client slept\n");
2968 goto exit_err;
2969 }
2970 }
2971
2972 return;
2973
2974exit_err:
2975 pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
2976 test_ch->name);
2977 test_ch->test_completed = 1;
2978 test_ch->test_result = TEST_FAILED;
2979 check_test_completion();
2980 return;
2981}
2982
2983
2984/**
2985 * LPM Test while the host wakes up the modem
2986 */
2987static void lpm_test_host_waker(struct test_channel *test_ch)
2988{
2989 pr_info(TEST_MODULE_NAME ": %s - START\n", __func__);
2990 wait_event(test_ch->wait_q, atomic_read(&test_ch->wakeup_client));
2991 atomic_set(&test_ch->wakeup_client, 0);
2992
2993 pr_info(TEST_MODULE_NAME ": %s - Sending the config_msg to wakeup "
2994 " the client\n", __func__);
2995 send_config_msg(test_ch);
2996
2997 lpm_test(test_ch);
2998}
2999
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003000static void notify(void *priv, unsigned channel_event);
3001
3002/**
3003 * Writes number of packets into test channel
3004 * @test_ch: test channel control struct
3005 * @burst_size: number of packets to send
3006 */
3007static int write_packet_burst(struct test_channel *test_ch,
3008 int burst_size)
3009{
3010 int ret = 0;
3011 int packet_count = 0;
3012 unsigned int random_num = 0;
3013 int size = test_ch->packet_length; /* first packet size */
3014 u32 write_avail = 0;
3015
3016 while (packet_count < burst_size) {
3017 /* wait for data ready event */
3018 write_avail = sdio_write_avail(test_ch->ch);
3019 TEST_DBG(TEST_MODULE_NAME ":%s write_avail=%d,size=%d on chan"
3020 " %s\n", __func__,
3021 write_avail, size, test_ch->name);
3022 if (write_avail < size) {
3023 TEST_DBG(TEST_MODULE_NAME ":%s wait for event on"
3024 " chan %s\n", __func__, test_ch->name);
3025 wait_event(test_ch->wait_q,
3026 atomic_read(&test_ch->tx_notify_count));
3027 atomic_dec(&test_ch->tx_notify_count);
3028 }
3029 write_avail = sdio_write_avail(test_ch->ch);
3030 if (write_avail < size) {
3031 pr_info(TEST_MODULE_NAME ":%s not enough write"
3032 " avail %d, need %d on chan %s\n",
3033 __func__, write_avail, size,
3034 test_ch->name);
3035 continue;
3036 }
3037 ret = sdio_write(test_ch->ch, test_ch->buf, size);
3038 if (ret) {
3039 pr_err(TEST_MODULE_NAME ":%s sdio_write "
3040 "failed (%d) on chan %s\n", __func__,
3041 ret, test_ch->name);
3042 break;
3043 }
3044 udelay(1000); /*low bus usage while running number of channels*/
3045 TEST_DBG(TEST_MODULE_NAME ":%s() successfully write %d bytes"
3046 ", packet_count=%d on chan %s\n", __func__,
3047 size, packet_count, test_ch->name);
3048 test_ch->tx_bytes += size;
3049 packet_count++;
3050 /* get next packet size */
3051 random_num = get_random_int();
3052 size = (random_num % test_ch->packet_length) + 1;
3053 }
3054 return ret;
3055}
3056/**
3057 * Reads packet from test channel and checks that packet number
3058 * encoded into the packet is equal to packet_counter
3059 *
3060 * @test_ch: test channel
3061 * @size: expected packet size
3062 * @packet_counter: number to validate readed packet
3063 */
3064static int read_data_from_channel(struct test_channel *test_ch,
3065 unsigned int size,
3066 int packet_counter)
3067{
3068 u32 read_avail = 0;
3069 int ret = 0;
3070
3071 if (!test_ch->ch->is_packet_mode) {
3072 pr_err(TEST_MODULE_NAME
3073 ":%s:not packet mode ch %s\n",
3074 __func__, test_ch->name);
3075 return -EINVAL;
3076 }
3077 read_avail = sdio_read_avail(test_ch->ch);
3078 /* wait for read data ready event */
3079 if (read_avail < size) {
3080 TEST_DBG(TEST_MODULE_NAME ":%s() wait for rx data on "
3081 "chan %s\n", __func__, test_ch->name);
3082 wait_event(test_ch->wait_q,
3083 atomic_read(&test_ch->rx_notify_count));
3084 atomic_dec(&test_ch->rx_notify_count);
3085 }
3086 read_avail = sdio_read_avail(test_ch->ch);
3087 TEST_DBG(TEST_MODULE_NAME ":%s read_avail=%d bytes on chan %s\n",
3088 __func__, read_avail, test_ch->name);
3089
3090 if (read_avail != size) {
3091 pr_err(TEST_MODULE_NAME
3092 ":read_avail size %d for chan %s not as "
3093 "expected size %d\n",
3094 read_avail, test_ch->name, size);
3095 return -EINVAL;
3096 }
3097
3098 ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
3099 if (ret) {
3100 pr_err(TEST_MODULE_NAME ":%s() sdio_read for chan %s (%d)\n",
3101 __func__, test_ch->name, -ret);
3102 return ret;
3103 }
3104 if ((test_ch->buf[0] != packet_counter) && (size != 1)) {
3105 pr_err(TEST_MODULE_NAME ":Read WRONG DATA"
3106 " for chan %s, size=%d\n",
3107 test_ch->name, size);
3108 return -EINVAL;
3109 }
3110 return 0;
3111}
3112
3113/**
3114 * Test close channel feature:
3115 * 1. write random packet number into channel
3116 * 2. read some data from channel (do this only for second half of
3117 * requested packets to send).
3118 * 3. close && re-open then repeat 1.
3119 *
3120 * Total packets to send: test_ch->config_msg.num_packets.
3121 * Burst size is random in [1..test_ch->max_burst_size] range
3122 * Packet size is random in [1..test_ch->packet_length]
3123 */
3124static void open_close_test(struct test_channel *test_ch)
3125{
3126 int ret = 0;
3127 u32 read_avail = 0;
3128 int total_packet_count = 0;
3129 int size = test_ch->packet_length;
3130 u16 *buf16 = (u16 *) test_ch->buf;
3131 int i;
3132 int max_packet_count = 0;
3133 unsigned int random_num = 0;
3134 int curr_burst_size = test_ch->max_burst_size;
3135
3136 /* the test sends configured number of packets in
3137 2 portions: first without reading between write bursts,
3138 second with it */
3139 max_packet_count = test_ch->config_msg.num_packets / 2;
3140
3141 pr_info(TEST_MODULE_NAME ":%s channel %s, total packets:%d,"
3142 " max packet size %d, max burst size:%d\n",
3143 __func__, test_ch->name,
3144 test_ch->config_msg.num_packets, test_ch->packet_length,
3145 test_ch->max_burst_size);
3146 for (i = 0 ; i < size / 2 ; i++)
3147 buf16[i] = (u16) (i & 0xFFFF);
3148
3149 for (i = 0; i < 2 ; i++) {
3150 total_packet_count = 0;
3151 while (total_packet_count < max_packet_count) {
3152 if (test_ctx->exit_flag) {
3153 pr_info(TEST_MODULE_NAME ":%s exit test\n",
3154 __func__);
3155 return;
3156 }
3157 test_ch->buf[0] = total_packet_count;
3158 random_num = get_random_int();
3159 curr_burst_size = (random_num %
3160 test_ch->max_burst_size) + 1;
3161
3162 /* limit burst size to send
3163 * no more than configured packets */
3164 if (curr_burst_size + total_packet_count >
3165 max_packet_count) {
3166 curr_burst_size = max_packet_count -
3167 total_packet_count;
3168 }
3169 TEST_DBG(TEST_MODULE_NAME ":%s Current burst size:%d"
3170 " on chan %s\n", __func__,
3171 curr_burst_size, test_ch->name);
3172 ret = write_packet_burst(test_ch, curr_burst_size);
3173 if (ret) {
3174 pr_err(TEST_MODULE_NAME ":%s write burst failed (%d), ch %s\n",
3175 __func__, ret, test_ch->name);
3176 goto exit_err;
3177 }
3178 if (i > 0) {
3179 /* read from channel */
3180 ret = read_data_from_channel(test_ch, size,
3181 total_packet_count);
3182 if (ret) {
3183 pr_err(TEST_MODULE_NAME ":%s read"
3184 " failed:%d, chan %s\n",
3185 __func__, ret,
3186 test_ch->name);
3187 goto exit_err;
3188 }
3189 }
3190 TEST_DBG(TEST_MODULE_NAME ":%s before close, ch %s\n",
3191 __func__, test_ch->name);
3192 ret = sdio_close(test_ch->ch);
3193 if (ret) {
3194 pr_err(TEST_MODULE_NAME":%s close channel %s"
3195 " failed (%d)\n",
3196 __func__, test_ch->name, ret);
3197 goto exit_err;
3198 } else {
3199 TEST_DBG(TEST_MODULE_NAME":%s close channel %s"
3200 " success\n", __func__,
3201 test_ch->name);
3202 total_packet_count += curr_burst_size;
3203 atomic_set(&test_ch->rx_notify_count, 0);
3204 atomic_set(&test_ch->tx_notify_count, 0);
3205 atomic_set(&test_ch->any_notify_count, 0);
3206 }
3207 TEST_DBG(TEST_MODULE_NAME ":%s before open, ch %s\n",
3208 __func__, test_ch->name);
3209 ret = sdio_open(test_ch->name , &test_ch->ch,
3210 test_ch, notify);
3211 if (ret) {
3212 pr_err(TEST_MODULE_NAME":%s open channel %s"
3213 " failed (%d)\n",
3214 __func__, test_ch->name, ret);
3215 goto exit_err;
3216 } else {
3217 read_avail = sdio_read_avail(test_ch->ch);
3218 if (read_avail > 0) {
3219 pr_err(TEST_MODULE_NAME": after open"
3220 " ch %s read_availis not zero"
3221 " (%d bytes)\n",
3222 test_ch->name, read_avail);
3223 goto exit_err;
3224 }
3225 }
3226 TEST_DBG(TEST_MODULE_NAME ":%s total tx = %d,"
3227 " packet# = %d, size = %d for ch %s\n",
3228 __func__, test_ch->tx_bytes,
3229 total_packet_count, size,
3230 test_ch->name);
3231 } /* end of while */
3232 }
3233 pr_info(TEST_MODULE_NAME ":%s Test end: total rx bytes = 0x%x,"
3234 " total tx bytes = 0x%x for chan %s\n", __func__,
3235 test_ch->rx_bytes, test_ch->tx_bytes, test_ch->name);
3236 pr_info(TEST_MODULE_NAME ":%s TEST PASS for chan %s.\n", __func__,
3237 test_ch->name);
3238 test_ch->test_completed = 1;
3239 test_ch->test_result = TEST_PASSED;
3240 check_test_completion();
3241 return;
3242exit_err:
3243 pr_info(TEST_MODULE_NAME ":%s TEST FAIL for chan %s.\n", __func__,
3244 test_ch->name);
3245 test_ch->test_completed = 1;
3246 test_ch->test_result = TEST_FAILED;
3247 check_test_completion();
3248 return;
3249}
3250
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003251/**
3252 * sender Test
3253 */
3254static void sender_test(struct test_channel *test_ch)
3255{
3256 int ret = 0 ;
3257 u32 read_avail = 0;
3258 u32 write_avail = 0;
3259 int packet_count = 0;
3260 int size = 512;
3261 u16 *buf16 = (u16 *) test_ch->buf;
3262 int i;
3263 int max_packet_count = 10000;
3264 int random_num = 0;
3265
3266 max_packet_count = test_ch->config_msg.num_packets;
3267
3268 for (i = 0 ; i < size / 2 ; i++)
3269 buf16[i] = (u16) (i & 0xFFFF);
3270
3271
3272 pr_info(TEST_MODULE_NAME
3273 ":SENDER TEST START for chan %s\n", test_ch->name);
3274
3275 while (packet_count < max_packet_count) {
3276
3277 if (test_ctx->exit_flag) {
3278 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
3279 return;
3280 }
3281
3282 random_num = get_random_int();
3283 size = (random_num % test_ch->packet_length) + 1;
3284
3285 TEST_DBG(TEST_MODULE_NAME "SENDER WAIT FOR EVENT for chan %s\n",
3286 test_ch->name);
3287
3288 /* wait for data ready event */
3289 write_avail = sdio_write_avail(test_ch->ch);
3290 TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
3291 if (write_avail < size) {
3292 wait_event(test_ch->wait_q,
3293 atomic_read(&test_ch->tx_notify_count));
3294 atomic_dec(&test_ch->tx_notify_count);
3295 }
3296
3297 write_avail = sdio_write_avail(test_ch->ch);
3298 TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
3299 if (write_avail < size) {
3300 pr_info(TEST_MODULE_NAME ":not enough write avail.\n");
3301 continue;
3302 }
3303
3304 test_ch->buf[0] = packet_count;
3305
3306 ret = sdio_write(test_ch->ch, test_ch->buf, size);
3307 if (ret) {
3308 pr_info(TEST_MODULE_NAME ":sender sdio_write err=%d.\n",
3309 -ret);
3310 goto exit_err;
3311 }
3312
3313 /* wait for read data ready event */
3314 TEST_DBG(TEST_MODULE_NAME ":sender wait for rx data for "
3315 "chan %s\n",
3316 test_ch->name);
3317 read_avail = sdio_read_avail(test_ch->ch);
3318 wait_event(test_ch->wait_q,
3319 atomic_read(&test_ch->rx_notify_count));
3320 atomic_dec(&test_ch->rx_notify_count);
3321
3322 read_avail = sdio_read_avail(test_ch->ch);
3323
3324 if (read_avail != size) {
3325 pr_info(TEST_MODULE_NAME
3326 ":read_avail size %d for chan %s not as "
3327 "expected size %d.\n",
3328 read_avail, test_ch->name, size);
3329 goto exit_err;
3330 }
3331
3332 memset(test_ch->buf, 0x00, size);
3333
3334 ret = sdio_read(test_ch->ch, test_ch->buf, size);
3335 if (ret) {
3336 pr_info(TEST_MODULE_NAME ":sender sdio_read for chan %s"
3337 " err=%d.\n",
3338 test_ch->name, -ret);
3339 goto exit_err;
3340 }
3341
3342
3343 if ((test_ch->buf[0] != packet_count) && (size != 1)) {
3344 pr_info(TEST_MODULE_NAME ":sender sdio_read WRONG DATA"
3345 " for chan %s, size=%d\n",
3346 test_ch->name, size);
3347 goto exit_err;
3348 }
3349
3350 test_ch->tx_bytes += size;
3351 test_ch->rx_bytes += size;
3352 packet_count++;
3353
3354 TEST_DBG(TEST_MODULE_NAME
3355 ":sender total rx bytes = 0x%x , packet#=%d, size=%d"
3356 " for chan %s\n",
3357 test_ch->rx_bytes, packet_count, size, test_ch->name);
3358 TEST_DBG(TEST_MODULE_NAME
3359 ":sender total tx bytes = 0x%x , packet#=%d, size=%d"
3360 " for chan %s\n",
3361 test_ch->tx_bytes, packet_count, size, test_ch->name);
3362
3363 } /* end of while */
3364
3365 pr_info(TEST_MODULE_NAME
3366 ":SENDER TEST END: total rx bytes = 0x%x, "
3367 " total tx bytes = 0x%x for chan %s\n",
3368 test_ch->rx_bytes, test_ch->tx_bytes, test_ch->name);
3369
3370 pr_info(TEST_MODULE_NAME ": TEST PASS for chan %s.\n",
3371 test_ch->name);
3372 test_ch->test_completed = 1;
3373 test_ch->test_result = TEST_PASSED;
3374 check_test_completion();
3375 return;
3376
3377exit_err:
3378 pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
3379 test_ch->name);
3380 test_ch->test_completed = 1;
3381 test_ch->test_result = TEST_FAILED;
3382 check_test_completion();
3383 return;
3384}
3385
3386/**
3387 * A2 Perf Test
3388 */
3389static void a2_performance_test(struct test_channel *test_ch)
3390{
3391 int ret = 0 ;
3392 u32 read_avail = 0;
3393 u32 write_avail = 0;
3394 int tx_packet_count = 0;
3395 int rx_packet_count = 0;
3396 int size = 0;
3397 u16 *buf16 = (u16 *) test_ch->buf;
3398 int i;
3399 int total_bytes = 0;
3400 int max_packets = 10000;
3401 u32 packet_size = test_ch->buf_size;
3402 int rand_size = 0;
3403
3404 u64 start_jiffy, end_jiffy, delta_jiffies;
3405 unsigned int time_msec = 0;
3406 u32 throughput = 0;
3407
3408 max_packets = test_ch->config_msg.num_packets;
3409 packet_size = test_ch->packet_length;
3410
3411 for (i = 0; i < packet_size / 2; i++)
3412 buf16[i] = (u16) (i & 0xFFFF);
3413
3414 pr_info(TEST_MODULE_NAME ": A2 PERFORMANCE TEST START for chan %s\n",
3415 test_ch->name);
3416
3417 start_jiffy = get_jiffies_64(); /* read the current time */
3418
3419 while (tx_packet_count < max_packets) {
3420
3421 if (test_ctx->exit_flag) {
3422 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
3423 return;
3424 }
3425
3426 if (test_ch->random_packet_size) {
3427 rand_size = get_random_int();
3428 packet_size = (rand_size % test_ch->packet_length) + 1;
3429 if (packet_size < A2_MIN_PACKET_SIZE)
3430 packet_size = A2_MIN_PACKET_SIZE;
3431 }
3432
3433 /* wait for data ready event */
3434 /* use a func to avoid compiler optimizations */
3435 write_avail = sdio_write_avail(test_ch->ch);
3436 read_avail = sdio_read_avail(test_ch->ch);
3437 TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d, "
3438 "read_avail=%d for chan %s\n",
3439 test_ch->name, write_avail, read_avail,
3440 test_ch->name);
3441 if ((write_avail == 0) && (read_avail == 0)) {
3442 wait_event(test_ch->wait_q,
3443 atomic_read(&test_ch->any_notify_count));
3444 atomic_set(&test_ch->any_notify_count, 0);
3445 }
3446
3447 write_avail = sdio_write_avail(test_ch->ch);
3448 TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d\n",
3449 test_ch->name, write_avail);
3450 if (write_avail > 0) {
3451 size = min(packet_size, write_avail) ;
3452 TEST_DBG(TEST_MODULE_NAME ":tx size = %d for chan %s\n",
3453 size, test_ch->name);
3454 test_ch->buf[0] = tx_packet_count;
3455 test_ch->buf[(size/4)-1] = tx_packet_count;
3456
3457 ret = sdio_write(test_ch->ch, test_ch->buf, size);
3458 if (ret) {
3459 pr_info(TEST_MODULE_NAME ":sdio_write err=%d"
3460 " for chan %s\n",
3461 -ret, test_ch->name);
3462 goto exit_err;
3463 }
3464 tx_packet_count++;
3465 test_ch->tx_bytes += size;
3466 }
3467
3468 read_avail = sdio_read_avail(test_ch->ch);
3469 TEST_DBG(TEST_MODULE_NAME ":channel %s, read_avail=%d\n",
3470 test_ch->name, read_avail);
3471 if (read_avail > 0) {
3472 size = min(packet_size, read_avail);
3473 pr_debug(TEST_MODULE_NAME ":rx size = %d.\n", size);
3474 ret = sdio_read(test_ch->ch, test_ch->buf, size);
3475 if (ret) {
3476 pr_info(TEST_MODULE_NAME ": sdio_read size %d "
3477 " err=%d"
3478 " for chan %s\n",
3479 size, -ret, test_ch->name);
3480 goto exit_err;
3481 }
3482 rx_packet_count++;
3483 test_ch->rx_bytes += size;
3484 }
3485
3486 TEST_DBG(TEST_MODULE_NAME
3487 ":total rx bytes = %d , rx_packet#=%d"
3488 " for chan %s\n",
3489 test_ch->rx_bytes, rx_packet_count, test_ch->name);
3490 TEST_DBG(TEST_MODULE_NAME
3491 ":total tx bytes = %d , tx_packet#=%d"
3492 " for chan %s\n",
3493 test_ch->tx_bytes, tx_packet_count, test_ch->name);
3494
3495 } /* while (tx_packet_count < max_packets ) */
3496
3497 end_jiffy = get_jiffies_64(); /* read the current time */
3498
3499 delta_jiffies = end_jiffy - start_jiffy;
3500 time_msec = jiffies_to_msecs(delta_jiffies);
3501
3502 pr_info(TEST_MODULE_NAME ":total rx bytes = 0x%x , rx_packet#=%d for"
3503 " chan %s.\n",
3504 test_ch->rx_bytes, rx_packet_count, test_ch->name);
3505 pr_info(TEST_MODULE_NAME ":total tx bytes = 0x%x , tx_packet#=%d"
3506 " for chan %s.\n",
3507 test_ch->tx_bytes, tx_packet_count, test_ch->name);
3508
3509 total_bytes = (test_ch->tx_bytes + test_ch->rx_bytes);
3510 pr_err(TEST_MODULE_NAME ":total bytes = %d, time msec = %d"
3511 " for chan %s\n",
3512 total_bytes , (int) time_msec, test_ch->name);
3513
3514 if (!test_ch->random_packet_size) {
3515 throughput = (total_bytes / time_msec) * 8 / 1000;
3516 pr_err(TEST_MODULE_NAME ":Performance = %d Mbit/sec for "
3517 "chan %s\n",
3518 throughput, test_ch->name);
3519 }
3520
3521#ifdef CONFIG_DEBUG_FS
3522 switch (test_ch->ch_id) {
3523 case SDIO_DUN:
3524 test_ctx->debug.dun_throughput = throughput;
3525 break;
3526 case SDIO_RMNT:
3527 test_ctx->debug.rmnt_throughput = throughput;
3528 break;
3529 default:
3530 pr_err(TEST_MODULE_NAME "No debugfs for this channel "
3531 "throughput");
3532 }
3533#endif
3534
3535 pr_err(TEST_MODULE_NAME ": A2 PERFORMANCE TEST END for chan %s.\n",
3536 test_ch->name);
3537
3538 pr_err(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
3539 test_ch->test_completed = 1;
3540 test_ch->test_result = TEST_PASSED;
3541 check_test_completion();
3542 return;
3543
3544exit_err:
3545 pr_err(TEST_MODULE_NAME ": TEST FAIL for chan %s\n", test_ch->name);
3546 test_ch->test_completed = 1;
3547 test_ch->test_result = TEST_FAILED;
3548 check_test_completion();
3549 return;
3550}
3551
3552/**
Maya Erez53508c12011-08-01 14:04:03 +03003553 * rx_cleanup
3554 * This function reads all the messages sent by the modem until
3555 * the read_avail is 0 after 1 second of sleep.
3556 * The function returns the number of packets that was received.
3557 */
3558static void rx_cleanup(struct test_channel *test_ch, int *rx_packet_count)
3559{
3560 int read_avail = 0;
3561 int ret = 0;
3562
3563 read_avail = sdio_read_avail(test_ch->ch);
3564 TEST_DBG(TEST_MODULE_NAME ":channel %s, read_avail=%d\n",
3565 test_ch->name, read_avail);
3566
3567 /* If no pending messages, wait to see if the modem sends data */
3568 if (read_avail == 0) {
3569 msleep(1000);
3570 read_avail = sdio_read_avail(test_ch->ch);
3571 }
3572
3573 while (read_avail > 0) {
3574 TEST_DBG(TEST_MODULE_NAME ": read_avail=%d for ch %s\n",
3575 read_avail, test_ch->name);
3576
3577 ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
3578 if (ret) {
3579 pr_info(TEST_MODULE_NAME ": sdio_read size %d "
3580 " err=%d for chan %s\n",
3581 read_avail, -ret, test_ch->name);
3582 break;
3583 }
3584 (*rx_packet_count)++;
3585 test_ch->rx_bytes += read_avail;
3586 read_avail = sdio_read_avail(test_ch->ch);
3587 if (read_avail == 0) {
3588 msleep(1000);
3589 read_avail = sdio_read_avail(test_ch->ch);
3590 }
3591 }
3592 pr_info(TEST_MODULE_NAME ": finished cleanup for ch %s, "
3593 "rx_packet_count=%d, total rx bytes=%d\n",
3594 test_ch->name, *rx_packet_count, test_ch->rx_bytes);
3595}
3596
3597
3598/**
3599 * A2 RTT Test
3600 * This function sends a packet and calculate the RTT time of
3601 * this packet.
3602 * The test also calculte Min, Max and Average RTT
3603 */
3604static void a2_rtt_test(struct test_channel *test_ch)
3605{
3606 int ret = 0 ;
3607 u32 read_avail = 0;
3608 u32 write_avail = 0;
3609 int tx_packet_count = 0;
3610 int rx_packet_count = 0;
3611 u16 *buf16 = (u16 *) test_ch->buf;
3612 int i;
3613 int max_packets = test_ch->config_msg.num_packets;
3614 u32 packet_size = test_ch->packet_length;
3615 s64 start_time, end_time;
3616 int delta_usec = 0;
3617 int time_average = 0;
3618 int min_delta_usec = 0xFFFF;
3619 int max_delta_usec = 0;
3620 int total_time = 0;
3621 int expected_read_size = 0;
3622
3623 for (i = 0; i < packet_size / 2; i++)
3624 buf16[i] = (u16) (i & 0xFFFF);
3625
3626 pr_info(TEST_MODULE_NAME ": A2 RTT TEST START for chan %s\n",
3627 test_ch->name);
3628
3629 rx_cleanup(test_ch, &rx_packet_count);
3630 rx_packet_count = 0;
3631
3632 while (tx_packet_count < max_packets) {
3633 if (test_ctx->exit_flag) {
3634 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
3635 return;
3636 }
3637 start_time = 0;
3638 end_time = 0;
3639
3640 /* Allow sdio_al to go to sleep to change the read_threshold
3641 * to 1
3642 */
3643 msleep(100);
3644
3645 /* wait for data ready event */
3646 write_avail = sdio_write_avail(test_ch->ch);
3647 TEST_DBG(TEST_MODULE_NAME ":ch %s: write_avail=%d\n",
3648 test_ch->name, write_avail);
3649 if (write_avail == 0) {
3650 wait_event(test_ch->wait_q,
3651 atomic_read(&test_ch->tx_notify_count));
3652 atomic_dec(&test_ch->tx_notify_count);
3653 }
3654
3655 write_avail = sdio_write_avail(test_ch->ch);
3656 TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d\n",
3657 test_ch->name, write_avail);
3658 if (write_avail > 0) {
3659 TEST_DBG(TEST_MODULE_NAME ":tx size = %d for chan %s\n",
3660 packet_size, test_ch->name);
3661 test_ch->buf[0] = tx_packet_count;
3662
3663 start_time = ktime_to_us(ktime_get());
3664 ret = sdio_write(test_ch->ch, test_ch->buf,
3665 packet_size);
3666 if (ret) {
3667 pr_err(TEST_MODULE_NAME ":sdio_write err=%d"
3668 " for chan %s\n",
3669 -ret, test_ch->name);
3670 goto exit_err;
3671 }
3672 tx_packet_count++;
3673 test_ch->tx_bytes += packet_size;
3674 } else {
3675 pr_err(TEST_MODULE_NAME ": Invalid write_avail"
3676 " %d for chan %s\n",
3677 write_avail, test_ch->name);
3678 goto exit_err;
3679 }
3680
3681 expected_read_size = packet_size + A2_HEADER_OVERHEAD;
3682
3683 read_avail = sdio_read_avail(test_ch->ch);
3684 TEST_DBG(TEST_MODULE_NAME ":channel %s, read_avail=%d\n",
3685 test_ch->name, read_avail);
3686 while (read_avail < expected_read_size) {
3687 wait_event(test_ch->wait_q,
3688 atomic_read(&test_ch->rx_notify_count));
3689 atomic_dec(&test_ch->rx_notify_count);
3690 read_avail = sdio_read_avail(test_ch->ch);
3691 }
3692
3693 if (read_avail >= expected_read_size) {
3694 pr_debug(TEST_MODULE_NAME ":read_avail=%d for ch %s.\n",
3695 read_avail, test_ch->name);
3696 ret = sdio_read(test_ch->ch, test_ch->buf,
3697 expected_read_size);
3698 if (ret) {
3699 pr_info(TEST_MODULE_NAME ": sdio_read size %d "
3700 " err=%d for chan %s\n",
3701 expected_read_size, -ret,
3702 test_ch->name);
3703 goto exit_err;
3704 }
3705 end_time = ktime_to_us(ktime_get());
3706 rx_packet_count++;
3707 test_ch->rx_bytes += expected_read_size;
3708 } else {
3709 pr_info(TEST_MODULE_NAME ": Invalid read_avail "
3710 "%d for chan %s\n",
3711 read_avail, test_ch->name);
3712 goto exit_err;
3713 }
3714
3715 delta_usec = (int)(end_time - start_time);
3716 total_time += delta_usec;
3717 if (delta_usec < min_delta_usec)
3718 min_delta_usec = delta_usec;
3719 if (delta_usec > max_delta_usec)
3720 max_delta_usec = delta_usec;
3721
3722 TEST_DBG(TEST_MODULE_NAME
3723 ":RTT time=%d for packet #%d for chan %s\n",
3724 delta_usec, tx_packet_count, test_ch->name);
3725
3726 } /* while (tx_packet_count < max_packets ) */
3727
3728
3729 pr_info(TEST_MODULE_NAME ":total rx bytes = 0x%x , rx_packet#=%d for"
3730 " chan %s.\n",
3731 test_ch->rx_bytes, rx_packet_count, test_ch->name);
3732 pr_info(TEST_MODULE_NAME ":total tx bytes = 0x%x , tx_packet#=%d"
3733 " for chan %s.\n",
3734 test_ch->tx_bytes, tx_packet_count, test_ch->name);
3735
3736 time_average = total_time / tx_packet_count;
3737
3738 pr_info(TEST_MODULE_NAME ":Average RTT time = %d for chan %s\n",
3739 time_average, test_ch->name);
3740 pr_info(TEST_MODULE_NAME ":MIN RTT time = %d for chan %s\n",
3741 min_delta_usec, test_ch->name);
3742 pr_info(TEST_MODULE_NAME ":MAX RTT time = %d for chan %s\n",
3743 max_delta_usec, test_ch->name);
3744
3745 pr_info(TEST_MODULE_NAME ": A2 RTT TEST END for chan %s.\n",
3746 test_ch->name);
3747
3748 pr_info(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
3749 test_ch->test_completed = 1;
3750 test_ch->test_result = TEST_PASSED;
3751 check_test_completion();
3752 return;
3753
3754exit_err:
3755 pr_err(TEST_MODULE_NAME ": TEST FAIL for chan %s\n", test_ch->name);
3756 test_ch->test_completed = 1;
3757 test_ch->test_result = TEST_FAILED;
3758 check_test_completion();
3759 return;
3760}
3761
3762
3763/**
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003764 * sender No loopback Test
3765 */
3766static void sender_no_loopback_test(struct test_channel *test_ch)
3767{
3768 int ret = 0 ;
3769 u32 write_avail = 0;
3770 int packet_count = 0;
3771 int size = 512;
3772 u16 *buf16 = (u16 *) test_ch->buf;
3773 int i;
3774 int max_packet_count = 10000;
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003775 unsigned int random_num = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003776
3777 max_packet_count = test_ch->config_msg.num_packets;
3778
3779 for (i = 0 ; i < size / 2 ; i++)
3780 buf16[i] = (u16) (i & 0xFFFF);
3781
3782 pr_info(TEST_MODULE_NAME
3783 ":SENDER NO LP TEST START for chan %s\n", test_ch->name);
3784
3785 while (packet_count < max_packet_count) {
3786
3787 if (test_ctx->exit_flag) {
3788 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
3789 return;
3790 }
3791
3792 random_num = get_random_int();
3793 size = (random_num % test_ch->packet_length) + 1;
3794
3795 TEST_DBG(TEST_MODULE_NAME ":SENDER WAIT FOR EVENT "
3796 "for chan %s\n",
3797 test_ch->name);
3798
3799 /* wait for data ready event */
3800 write_avail = sdio_write_avail(test_ch->ch);
3801 TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
3802 if (write_avail < size) {
3803 wait_event(test_ch->wait_q,
3804 atomic_read(&test_ch->tx_notify_count));
3805 atomic_dec(&test_ch->tx_notify_count);
3806 }
3807
3808 write_avail = sdio_write_avail(test_ch->ch);
3809 TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
3810 if (write_avail < size) {
3811 pr_info(TEST_MODULE_NAME ":not enough write avail.\n");
3812 continue;
3813 }
3814
3815 test_ch->buf[0] = packet_count;
3816
3817 ret = sdio_write(test_ch->ch, test_ch->buf, size);
3818 if (ret) {
3819 pr_info(TEST_MODULE_NAME ":sender sdio_write err=%d.\n",
3820 -ret);
3821 goto exit_err;
3822 }
3823
3824 test_ch->tx_bytes += size;
3825 packet_count++;
3826
3827 TEST_DBG(TEST_MODULE_NAME
3828 ":sender total tx bytes = 0x%x , packet#=%d, size=%d"
3829 " for chan %s\n",
3830 test_ch->tx_bytes, packet_count, size, test_ch->name);
3831
3832 } /* end of while */
3833
3834 pr_info(TEST_MODULE_NAME
3835 ":SENDER TEST END: total tx bytes = 0x%x, "
3836 " for chan %s\n",
3837 test_ch->tx_bytes, test_ch->name);
3838
Yaniv Gardi3e327762011-07-27 11:11:04 +03003839 test_ch->modem_result_per_chan = wait_for_result_msg(test_ch);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003840
Yaniv Gardi3e327762011-07-27 11:11:04 +03003841 if (test_ch->modem_result_per_chan) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003842 pr_info(TEST_MODULE_NAME ": TEST PASS for chan %s.\n",
3843 test_ch->name);
3844 test_ch->test_result = TEST_PASSED;
3845 } else {
3846 pr_info(TEST_MODULE_NAME ": TEST FAILURE for chan %s.\n",
3847 test_ch->name);
3848 test_ch->test_result = TEST_FAILED;
3849 }
3850 test_ch->test_completed = 1;
3851 check_test_completion();
3852 return;
3853
3854exit_err:
3855 pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
3856 test_ch->name);
3857 test_ch->test_completed = 1;
3858 test_ch->test_result = TEST_FAILED;
3859 check_test_completion();
3860 return;
3861}
3862
Maya Erez8afd564f2011-08-24 15:57:06 +03003863
3864/**
3865 * Modem reset Test
3866 * The test verifies that it finished sending all the packets
3867 * while there might be modem reset in the middle
3868 */
3869static void modem_reset_test(struct test_channel *test_ch)
3870{
3871 int ret = 0 ;
3872 u32 read_avail = 0;
3873 u32 write_avail = 0;
3874 int tx_packet_count = 0;
3875 int rx_packet_count = 0;
3876 int size = 0;
3877 u16 *buf16 = (u16 *) test_ch->buf;
3878 int i;
3879 int max_packets = 10000;
3880 u32 packet_size = test_ch->buf_size;
3881 int is_err = 0;
3882
3883 max_packets = test_ch->config_msg.num_packets;
3884 packet_size = test_ch->packet_length;
3885
3886 for (i = 0; i < packet_size / 2; i++)
3887 buf16[i] = (u16) (i & 0xFFFF);
3888
3889 pr_info(TEST_MODULE_NAME ": Modem Reset TEST START for chan %s\n",
3890 test_ch->name);
3891
3892 while (tx_packet_count < max_packets) {
3893
3894 if (test_ctx->exit_flag) {
3895 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
3896 return;
3897 }
3898
3899 if (test_ch->card_removed) {
3900 pr_info(TEST_MODULE_NAME ": card removal was detected "
3901 "for chan %s, tx_total=0x%x\n",
3902 test_ch->name, test_ch->tx_bytes);
3903 wait_event(test_ch->wait_q,
3904 atomic_read(&test_ch->card_detected_event));
3905 atomic_set(&test_ch->card_detected_event, 0);
3906 pr_info(TEST_MODULE_NAME ": card_detected_event "
3907 "for chan %s\n", test_ch->name);
3908 if (test_ch->card_removed)
3909 continue;
3910 is_err = 0;
3911 /* Need to wait for the modem to be ready */
3912 msleep(5000);
3913 pr_info(TEST_MODULE_NAME ": sending the config message "
3914 "for chan %s\n", test_ch->name);
3915 send_config_msg(test_ch);
3916 }
3917
3918 /* wait for data ready event */
3919 /* use a func to avoid compiler optimizations */
3920 write_avail = sdio_write_avail(test_ch->ch);
3921 read_avail = sdio_read_avail(test_ch->ch);
3922 TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d, "
3923 "read_avail=%d for chan %s\n",
3924 test_ch->name, write_avail, read_avail,
3925 test_ch->name);
3926 if ((write_avail == 0) && (read_avail == 0)) {
3927 wait_event(test_ch->wait_q,
3928 atomic_read(&test_ch->any_notify_count));
3929 atomic_set(&test_ch->any_notify_count, 0);
3930 }
3931 if (atomic_read(&test_ch->card_detected_event)) {
3932 atomic_set(&test_ch->card_detected_event, 0);
3933 pr_info(TEST_MODULE_NAME ": card_detected_event "
3934 "for chan %s, tx_total=0x%x\n",
3935 test_ch->name, test_ch->tx_bytes);
3936 if (test_ch->card_removed)
3937 continue;
3938 /* Need to wait for the modem to be ready */
3939 msleep(5000);
3940 is_err = 0;
3941 pr_info(TEST_MODULE_NAME ": sending the config message "
3942 "for chan %s\n", test_ch->name);
3943 send_config_msg(test_ch);
3944 }
3945
3946 write_avail = sdio_write_avail(test_ch->ch);
3947 TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d\n",
3948 test_ch->name, write_avail);
3949 if (write_avail > 0) {
3950 size = min(packet_size, write_avail) ;
3951 pr_debug(TEST_MODULE_NAME ":tx size = %d for chan %s\n",
3952 size, test_ch->name);
3953 test_ch->buf[0] = tx_packet_count;
3954 test_ch->buf[(size/4)-1] = tx_packet_count;
3955
3956 TEST_DBG(TEST_MODULE_NAME ":channel %s, sdio_write, "
3957 "size=%d\n", test_ch->name, size);
3958 if (is_err) {
3959 msleep(100);
3960 continue;
3961 }
3962 ret = sdio_write(test_ch->ch, test_ch->buf, size);
3963 if (ret) {
3964 pr_info(TEST_MODULE_NAME ":sdio_write err=%d"
3965 " for chan %s\n",
3966 -ret, test_ch->name);
3967 is_err = 1;
3968 msleep(20);
3969 continue;
3970 }
3971 tx_packet_count++;
3972 test_ch->tx_bytes += size;
3973 test_ch->config_msg.num_packets--;
3974 }
3975
3976 read_avail = sdio_read_avail(test_ch->ch);
3977 TEST_DBG(TEST_MODULE_NAME ":channel %s, read_avail=%d\n",
3978 test_ch->name, read_avail);
3979 if (read_avail > 0) {
3980 size = min(packet_size, read_avail);
3981 pr_debug(TEST_MODULE_NAME ":rx size = %d.\n", size);
3982 TEST_DBG(TEST_MODULE_NAME ":channel %s, sdio_read, "
3983 "size=%d\n", test_ch->name, size);
3984 if (is_err) {
3985 msleep(100);
3986 continue;
3987 }
3988 ret = sdio_read(test_ch->ch, test_ch->buf, size);
3989 if (ret) {
3990 pr_info(TEST_MODULE_NAME ": sdio_read size %d "
3991 " err=%d"
3992 " for chan %s\n",
3993 size, -ret, test_ch->name);
3994 is_err = 1;
3995 msleep(20);
3996 continue;
3997 }
3998 rx_packet_count++;
3999 test_ch->rx_bytes += size;
4000 }
4001
4002 TEST_DBG(TEST_MODULE_NAME
4003 ":total rx bytes = %d , rx_packet#=%d"
4004 " for chan %s\n",
4005 test_ch->rx_bytes, rx_packet_count, test_ch->name);
4006 TEST_DBG(TEST_MODULE_NAME
4007 ":total tx bytes = %d , tx_packet#=%d"
4008 " for chan %s\n",
4009 test_ch->tx_bytes, tx_packet_count, test_ch->name);
4010
4011 udelay(500);
4012
4013 } /* while (tx_packet_count < max_packets ) */
4014
4015 rx_cleanup(test_ch, &rx_packet_count);
4016
4017 pr_info(TEST_MODULE_NAME ":total rx bytes = 0x%x , rx_packet#=%d for"
4018 " chan %s.\n",
4019 test_ch->rx_bytes, rx_packet_count, test_ch->name);
4020 pr_info(TEST_MODULE_NAME ":total tx bytes = 0x%x , tx_packet#=%d"
4021 " for chan %s.\n",
4022 test_ch->tx_bytes, tx_packet_count, test_ch->name);
4023
4024 pr_err(TEST_MODULE_NAME ": Modem Reset TEST END for chan %s.\n",
4025 test_ch->name);
4026
4027 pr_err(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
4028 test_ch->test_completed = 1;
4029 test_ch->test_result = TEST_PASSED;
4030 check_test_completion();
4031 return;
4032}
4033
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004034/**
4035 * Worker thread to handle the tests types
4036 */
4037static void worker(struct work_struct *work)
4038{
4039 struct test_channel *test_ch = NULL;
4040 struct test_work *test_work = container_of(work,
4041 struct test_work,
4042 work);
4043 int test_type = 0;
4044
4045 test_ch = test_work->test_ch;
4046
4047 if (test_ch == NULL) {
4048 pr_err(TEST_MODULE_NAME ":NULL test_ch\n");
4049 return;
4050 }
4051
4052 test_type = test_ch->test_type;
4053
4054 switch (test_type) {
4055 case SDIO_TEST_LOOPBACK_HOST:
4056 loopback_test(test_ch);
4057 break;
4058 case SDIO_TEST_LOOPBACK_CLIENT:
4059 sender_test(test_ch);
4060 break;
4061 case SDIO_TEST_PERF:
4062 a2_performance_test(test_ch);
4063 break;
4064 case SDIO_TEST_LPM_CLIENT_WAKER:
4065 lpm_test(test_ch);
4066 break;
4067 case SDIO_TEST_LPM_HOST_WAKER:
4068 lpm_test_host_waker(test_ch);
4069 break;
4070 case SDIO_TEST_HOST_SENDER_NO_LP:
4071 sender_no_loopback_test(test_ch);
4072 break;
4073 case SDIO_TEST_LPM_RANDOM:
4074 lpm_continuous_rand_test(test_ch);
Maya Erezf204e692011-08-12 22:00:13 +03004075 break;
Maya Erez53508c12011-08-01 14:04:03 +03004076 case SDIO_TEST_RTT:
4077 a2_rtt_test(test_ch);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004078 break;
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03004079 case SDIO_TEST_CLOSE_CHANNEL:
4080 open_close_test(test_ch);
4081 break;
Maya Erez8afd564f2011-08-24 15:57:06 +03004082 case SDIO_TEST_MODEM_RESET:
4083 modem_reset_test(test_ch);
4084 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004085 default:
4086 pr_err(TEST_MODULE_NAME ":Bad Test type = %d.\n",
4087 (int) test_type);
4088 }
4089}
4090
4091
4092/**
4093 * Notification Callback
4094 *
4095 * Notify the worker
4096 *
4097 */
4098static void notify(void *priv, unsigned channel_event)
4099{
4100 struct test_channel *test_ch = (struct test_channel *) priv;
4101
Yaniv Gardi3e327762011-07-27 11:11:04 +03004102 pr_debug(TEST_MODULE_NAME ": %s - notify event=%d.\n",
4103 __func__, channel_event);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004104
4105 if (test_ch->ch == NULL) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03004106 pr_info(TEST_MODULE_NAME ": %s - notify before ch ready.\n",
4107 __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004108 return;
4109 }
4110
4111 switch (channel_event) {
4112 case SDIO_EVENT_DATA_READ_AVAIL:
4113 atomic_inc(&test_ch->rx_notify_count);
4114 atomic_set(&test_ch->any_notify_count, 1);
Yaniv Gardi3e327762011-07-27 11:11:04 +03004115 TEST_DBG(TEST_MODULE_NAME ": %s - SDIO_EVENT_DATA_READ_AVAIL, "
4116 "any_notify_count=%d, rx_notify_count=%d\n",
4117 __func__,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004118 atomic_read(&test_ch->any_notify_count),
4119 atomic_read(&test_ch->rx_notify_count));
Yaniv Gardi3e327762011-07-27 11:11:04 +03004120 /*
4121 * when there is pending data on a channel we would like to
4122 * turn on the bit mask that implies that there is pending
4123 * data for that channel on that deivce
4124 */
4125 if (test_ch->test_device != NULL &&
4126 test_ch->test_type == SDIO_TEST_LPM_RANDOM) {
4127 spin_lock_irqsave(&test_ch->test_device->lpm_array_lock,
4128 test_ch->test_device->
4129 lpm_array_lock_flags);
4130 test_ch->test_device->read_avail_mask |=
4131 test_ch->channel_mask_id;
4132 test_ch->notify_counter_per_chan++;
4133
4134 lpm_test_update_entry(test_ch, LPM_NOTIFY, "NOTIFY", 0);
4135 spin_unlock_irqrestore(&test_ch->test_device->
4136 lpm_array_lock,
4137 test_ch->test_device->
4138 lpm_array_lock_flags);
4139 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004140 break;
4141
4142 case SDIO_EVENT_DATA_WRITE_AVAIL:
4143 atomic_inc(&test_ch->tx_notify_count);
4144 atomic_set(&test_ch->any_notify_count, 1);
Yaniv Gardi3e327762011-07-27 11:11:04 +03004145 TEST_DBG(TEST_MODULE_NAME ": %s - SDIO_EVENT_DATA_WRITE_AVAIL, "
4146 "any_notify_count=%d, tx_notify_count=%d\n",
4147 __func__,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004148 atomic_read(&test_ch->any_notify_count),
4149 atomic_read(&test_ch->tx_notify_count));
4150 break;
4151
4152 default:
4153 BUG();
4154 }
4155 wake_up(&test_ch->wait_q);
4156
4157}
4158
4159#ifdef CONFIG_MSM_SDIO_SMEM
4160static int sdio_smem_test_cb(int event)
4161{
4162 struct test_channel *tch = test_ctx->test_ch_arr[SDIO_SMEM];
4163 pr_debug(TEST_MODULE_NAME ":%s: Received event %d\n", __func__, event);
4164
4165 switch (event) {
4166 case SDIO_SMEM_EVENT_READ_DONE:
4167 tch->rx_bytes += SMEM_MAX_XFER_SIZE;
4168 if (tch->rx_bytes >= 40000000) {
4169 if (!tch->test_completed) {
4170 pr_info(TEST_MODULE_NAME ":SMEM test PASSED\n");
4171 tch->test_completed = 1;
4172 tch->test_result = TEST_PASSED;
4173 check_test_completion();
4174 }
4175
4176 }
4177 break;
4178 case SDIO_SMEM_EVENT_READ_ERR:
4179 pr_err(TEST_MODULE_NAME ":Read overflow, SMEM test FAILED\n");
4180 tch->test_completed = 1;
4181 tch->test_result = TEST_FAILED;
4182 check_test_completion();
4183 return -EIO;
4184 default:
4185 pr_err(TEST_MODULE_NAME ":Unhandled event\n");
4186 return -EINVAL;
4187 }
4188 return 0;
4189}
4190
4191static int sdio_smem_test_probe(struct platform_device *pdev)
4192{
4193 int ret = 0;
4194
4195 test_ctx->sdio_smem = container_of(pdev, struct sdio_smem_client,
4196 plat_dev);
4197
4198 test_ctx->sdio_smem->buf = test_ctx->smem_buf;
4199 test_ctx->sdio_smem->size = SMEM_MAX_XFER_SIZE;
4200 test_ctx->sdio_smem->cb_func = sdio_smem_test_cb;
4201 ret = sdio_smem_register_client();
4202 if (ret)
4203 pr_info(TEST_MODULE_NAME "%s: Error (%d) registering sdio_smem "
4204 "test client\n",
4205 __func__, ret);
4206 return ret;
4207}
4208
Maya Erez8afd564f2011-08-24 15:57:06 +03004209static struct platform_driver sdio_smem_client_drv = {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004210 .probe = sdio_smem_test_probe,
4211 .driver = {
4212 .name = "SDIO_SMEM_CLIENT",
4213 .owner = THIS_MODULE,
4214 },
4215};
4216#endif
4217
4218
4219static void default_sdio_al_test_release(struct device *dev)
4220{
4221 pr_info(MODULE_NAME ":platform device released.\n");
4222}
4223
4224static void sdio_test_lpm_timeout_handler(unsigned long data)
4225{
4226 struct test_channel *tch = (struct test_channel *)data;
4227
4228 pr_info(TEST_MODULE_NAME ": %s - LPM TEST TIMEOUT Expired after "
4229 "%d ms\n", __func__, tch->timeout_ms);
4230 tch->test_completed = 1;
4231 pr_info(TEST_MODULE_NAME ": %s - tch->test_result = TEST_FAILED\n",
4232 __func__);
4233 tch->test_completed = 1;
4234 tch->test_result = TEST_FAILED;
4235 check_test_completion();
4236 return;
4237}
4238
4239static void sdio_test_lpm_timer_handler(unsigned long data)
4240{
4241 struct test_channel *tch = (struct test_channel *)data;
4242
4243 pr_info(TEST_MODULE_NAME ": %s - LPM TEST Timer Expired after "
4244 "%d ms\n", __func__, tch->timer_interval_ms);
4245
4246 if (!tch) {
4247 pr_err(TEST_MODULE_NAME ": %s - LPM TEST FAILED. "
4248 "tch is NULL\n", __func__);
4249 return;
4250 }
4251
4252 if (!tch->ch) {
4253 pr_err(TEST_MODULE_NAME ": %s - LPM TEST FAILED. tch->ch "
4254 "is NULL\n", __func__);
4255 tch->test_result = TEST_FAILED;
4256 return;
4257 }
4258
4259 /* Verfiy that we voted for sleep */
4260 if (tch->is_ok_to_sleep) {
4261 tch->test_result = TEST_PASSED;
4262 pr_info(TEST_MODULE_NAME ": %s - 8K voted for sleep\n",
4263 __func__);
4264 } else {
4265 tch->test_result = TEST_FAILED;
4266 pr_info(TEST_MODULE_NAME ": %s - 8K voted against sleep\n",
4267 __func__);
4268
4269 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03004270
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004271 sdio_al_unregister_lpm_cb(tch->sdio_al_device);
4272
4273 if (tch->test_type == SDIO_TEST_LPM_HOST_WAKER) {
4274 atomic_set(&tch->wakeup_client, 1);
4275 wake_up(&tch->wait_q);
4276 }
4277}
4278
4279int sdio_test_wakeup_callback(void *device_handle, int is_vote_for_sleep)
4280{
4281 int i = 0;
4282
4283 TEST_DBG(TEST_MODULE_NAME ": %s is_vote_for_sleep=%d!!!",
4284 __func__, is_vote_for_sleep);
4285
4286 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
4287 struct test_channel *tch = test_ctx->test_ch_arr[i];
4288
4289 if ((!tch) || (!tch->is_used) || (!tch->ch_ready))
4290 continue;
4291 if (tch->sdio_al_device == device_handle) {
4292 tch->is_ok_to_sleep = is_vote_for_sleep;
4293
Yaniv Gardi3e327762011-07-27 11:11:04 +03004294 if (tch->test_type == SDIO_TEST_LPM_RANDOM) {
4295 spin_lock_irqsave(&tch->test_device->
4296 lpm_array_lock,
4297 tch->test_device->
4298 lpm_array_lock_flags);
Yaniv Gardi3e327762011-07-27 11:11:04 +03004299 if (is_vote_for_sleep == 1)
4300 lpm_test_update_entry(tch,
4301 LPM_SLEEP,
4302 "SLEEP ", 0);
4303 else
4304 lpm_test_update_entry(tch,
4305 LPM_WAKEUP,
4306 "WAKEUP", 0);
4307
4308 spin_unlock_irqrestore(&tch->test_device->
4309 lpm_array_lock,
4310 tch->test_device->
4311 lpm_array_lock_flags);
4312 break;
4313 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004314 }
4315 }
4316
Yaniv Gardi3e327762011-07-27 11:11:04 +03004317 return 0;
4318}
4319
4320static int sdio_test_find_dev(struct test_channel *tch)
4321{
4322 int j;
4323 int null_index = -1;
4324
4325 for (j = 0 ; j < MAX_NUM_OF_SDIO_DEVICES; ++j) {
4326
4327 struct sdio_test_device *test_dev =
4328 &test_ctx->test_dev_arr[j];
4329
4330 if (test_dev->sdio_al_device == NULL) {
4331 if (null_index == -1)
4332 null_index = j;
4333 continue;
4334 }
4335
4336 if (test_dev->sdio_al_device ==
4337 tch->ch->sdio_al_dev) {
4338 test_dev->open_channels_counter_to_recv++;
4339 test_dev->open_channels_counter_to_send++;
4340 tch->test_device = test_dev;
4341 /* setting mask id for pending data for
4342 this channel */
4343 tch->channel_mask_id = test_dev->next_mask_id;
4344 test_dev->next_mask_id *= 2;
4345 pr_info(TEST_MODULE_NAME ": %s - channel %s "
4346 "got read_mask_id = 0x%x. device "
4347 "next_mask_id=0x%x",
4348 __func__, tch->name, tch->channel_mask_id,
4349 test_dev->next_mask_id);
4350 break;
4351 }
4352 }
4353
4354 /*
4355 * happens ones a new device is "discovered" while testing. i.e
4356 * if testing a few channels, a new deivce will be "discovered" once
4357 * the first channel of a device is being tested
4358 */
4359 if (j == MAX_NUM_OF_SDIO_DEVICES) {
4360
4361 struct sdio_test_device *test_dev =
4362 &test_ctx->
4363 test_dev_arr[null_index];
4364 test_dev->sdio_al_device =
4365 tch->ch->sdio_al_dev;
4366
4367 test_ctx->number_of_active_devices++;
4368 test_ctx->max_number_of_devices++;
4369 test_dev->open_channels_counter_to_recv++;
4370 test_dev->open_channels_counter_to_send++;
4371 test_dev->next_avail_entry_in_array = 0;
4372 tch->test_device = test_dev;
4373 tch->test_device->array_size =
4374 LPM_ARRAY_SIZE;
4375 test_dev->modem_result_per_dev = 1;
4376 tch->modem_result_per_chan = 0;
4377
4378 spin_lock_init(&test_dev->
4379 lpm_array_lock);
Yaniv Gardi3e327762011-07-27 11:11:04 +03004380
4381 if (tch->test_type == SDIO_TEST_LPM_RANDOM) {
Maya Erez8afd564f2011-08-24 15:57:06 +03004382 pr_err(MODULE_NAME ": %s - "
4383 "Allocating Msg Array for "
4384 "Maximum open channels for device (%d) "
4385 "Channels. Array has %d entries",
4386 __func__,
4387 LPM_MAX_OPEN_CHAN_PER_DEV,
4388 test_dev->array_size);
Yaniv Gardi3e327762011-07-27 11:11:04 +03004389
4390 test_dev->lpm_arr =
4391 kzalloc(sizeof(
4392 struct lpm_entry_type) *
4393 tch->
4394 test_device->array_size,
4395 GFP_KERNEL);
4396
4397 if (!test_dev->lpm_arr) {
4398 pr_err(MODULE_NAME ": %s - "
4399 "lpm_arr is NULL",
4400 __func__);
4401 return -ENOMEM;
4402 }
4403 }
4404
4405 /*
4406 * in new device, initialize next_mask_id, and setting
4407 * mask_id to the channel
4408 */
4409 test_dev->next_mask_id = 0x1;
4410 tch->channel_mask_id = test_dev->next_mask_id;
4411 test_dev->next_mask_id *= 2;
4412 pr_info(TEST_MODULE_NAME ": %s - channel %s got "
4413 "read_mask_id = 0x%x. device next_mask_id=0x%x",
4414 __func__,
4415 tch->name,
4416 tch->channel_mask_id,
4417 test_dev->next_mask_id);
4418 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004419
4420 return 0;
4421}
4422
Yaniv Gardi3e327762011-07-27 11:11:04 +03004423static void check_test_result(void)
4424{
4425 int result = 1;
4426 int i = 0;
4427
4428 test_ctx->max_number_of_devices = 0;
4429
4430 pr_info(TEST_MODULE_NAME ": %s - Woke Up\n", __func__);
4431
4432 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
4433 struct test_channel *tch = test_ctx->test_ch_arr[i];
4434
4435 if ((!tch) || (!tch->is_used) || (!tch->ch_ready))
4436 continue;
4437
4438 if (tch->test_type == SDIO_TEST_LPM_RANDOM)
4439 result &= tch->test_device->final_result_per_dev;
4440 else
4441 if (tch->test_result == TEST_FAILED) {
4442 pr_info(TEST_MODULE_NAME ": %s - "
4443 "Test FAILED\n", __func__);
4444 test_ctx->test_result = TEST_FAILED;
4445 pr_err(TEST_MODULE_NAME ": %s - "
4446 "test_result %d",
4447 __func__, test_ctx->test_result);
4448 return;
4449 }
4450 }
4451
4452 if (result == 0) {
4453 pr_info(TEST_MODULE_NAME ": %s - Test FAILED\n", __func__);
4454 test_ctx->test_result = TEST_FAILED;
4455 pr_err(TEST_MODULE_NAME ": %s - "
4456 "test_result %d",
4457 __func__, test_ctx->test_result);
4458 return;
4459 }
4460
4461 pr_info(TEST_MODULE_NAME ": %s - Test PASSED", __func__);
4462 test_ctx->test_result = TEST_PASSED;
4463 pr_err(TEST_MODULE_NAME ": %s - "
4464 "test_result %d",
4465 __func__, test_ctx->test_result);
4466 return;
4467}
4468
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004469/**
4470 * Test Main
4471 */
4472static int test_start(void)
4473{
4474 int ret = -ENOMEM;
4475 int i;
4476
4477 pr_debug(TEST_MODULE_NAME ":Starting Test ....\n");
4478
4479 test_ctx->test_completed = 0;
4480 test_ctx->test_result = TEST_NO_RESULT;
4481 test_ctx->debug.dun_throughput = 0;
4482 test_ctx->debug.rmnt_throughput = 0;
Yaniv Gardi3e327762011-07-27 11:11:04 +03004483 test_ctx->number_of_active_devices = 0;
4484
4485 pr_err(TEST_MODULE_NAME ": %s - test_result %d",
4486 __func__, test_ctx->test_result);
4487
4488 memset(test_ctx->test_dev_arr, 0,
4489 sizeof(struct sdio_test_device)*MAX_NUM_OF_SDIO_DEVICES);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004490
4491 /* Open The Channels */
4492 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
4493 struct test_channel *tch = test_ctx->test_ch_arr[i];
4494
4495 if ((!tch) || (!tch->is_used))
4496 continue;
4497
4498 tch->rx_bytes = 0;
4499 tch->tx_bytes = 0;
4500
4501 atomic_set(&tch->tx_notify_count, 0);
4502 atomic_set(&tch->rx_notify_count, 0);
4503 atomic_set(&tch->any_notify_count, 0);
4504 atomic_set(&tch->wakeup_client, 0);
4505
Yaniv Gardi3e327762011-07-27 11:11:04 +03004506 /* in case there are values left from previous tests */
4507 tch->notify_counter_per_chan = 0;
4508
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004509 memset(tch->buf, 0x00, tch->buf_size);
4510 tch->test_result = TEST_NO_RESULT;
4511
4512 tch->test_completed = 0;
4513
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004514 if (!tch->ch_ready) {
4515 pr_info(TEST_MODULE_NAME ":openning channel %s\n",
4516 tch->name);
4517 tch->ch_ready = true;
4518 if (tch->ch_id == SDIO_SMEM) {
4519 test_ctx->smem_pdev.name = "SDIO_SMEM";
4520 test_ctx->smem_pdev.dev.release =
4521 default_sdio_al_test_release;
4522 platform_device_register(&test_ctx->smem_pdev);
4523 } else {
4524 ret = sdio_open(tch->name , &tch->ch, tch,
4525 notify);
4526 if (ret) {
4527 pr_info(TEST_MODULE_NAME
4528 ":openning channel %s failed\n",
4529 tch->name);
4530 tch->ch_ready = false;
Maya Erez8afd564f2011-08-24 15:57:06 +03004531 continue;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004532 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004533 }
4534 }
4535
Yaniv Gardi3e327762011-07-27 11:11:04 +03004536 if (tch->ch_id != SDIO_SMEM) {
4537 ret = sdio_test_find_dev(tch);
4538
4539 if (ret) {
4540 pr_err(TEST_MODULE_NAME ": %s - "
4541 "sdio_test_find_dev() returned with "
4542 "error", __func__);
4543 return -ENODEV;
4544 }
4545
4546 tch->sdio_al_device = tch->ch->sdio_al_dev;
4547 }
4548
4549 if ((tch->test_type == SDIO_TEST_LPM_HOST_WAKER) ||
4550 (tch->test_type == SDIO_TEST_LPM_CLIENT_WAKER) ||
4551 (tch->test_type == SDIO_TEST_LPM_RANDOM))
4552 sdio_al_register_lpm_cb(tch->sdio_al_device,
4553 sdio_test_wakeup_callback);
4554 }
4555
4556 /*
4557 * make some space between opening the channels and sending the
4558 * config messages
4559 */
4560 msleep(100);
4561
4562 /*
4563 * try to delay send_config_msg of all channels to after the point
4564 * when we open them all
4565 */
4566 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
4567 struct test_channel *tch = test_ctx->test_ch_arr[i];
4568
4569 if ((!tch) || (!tch->is_used))
4570 continue;
4571
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004572 if ((tch->ch_ready) && (tch->ch_id != SDIO_SMEM))
4573 send_config_msg(tch);
4574
4575 if ((tch->test_type == SDIO_TEST_LPM_HOST_WAKER) ||
4576 (tch->test_type == SDIO_TEST_LPM_CLIENT_WAKER) ||
4577 (tch->test_type == SDIO_TEST_LPM_RANDOM)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004578 if (tch->timer_interval_ms > 0) {
4579 pr_info(TEST_MODULE_NAME ": %s - init timer, "
Yaniv Gardi3e327762011-07-27 11:11:04 +03004580 "ms=%d\n",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004581 __func__, tch->timer_interval_ms);
4582 init_timer(&tch->timer);
4583 tch->timer.data = (unsigned long)tch;
4584 tch->timer.function =
4585 sdio_test_lpm_timer_handler;
4586 tch->timer.expires = jiffies +
4587 msecs_to_jiffies(tch->timer_interval_ms);
4588 add_timer(&tch->timer);
4589 }
4590 }
4591 }
4592
4593 pr_debug(TEST_MODULE_NAME ":queue_work..\n");
4594 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
4595 struct test_channel *tch = test_ctx->test_ch_arr[i];
4596
4597 if ((!tch) || (!tch->is_used) || (!tch->ch_ready) ||
4598 (tch->ch_id == SDIO_SMEM))
4599 continue;
Yaniv Gardi3e327762011-07-27 11:11:04 +03004600
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004601 queue_work(tch->workqueue, &tch->test_work.work);
4602 }
4603
Yaniv Gardi3e327762011-07-27 11:11:04 +03004604 pr_info(TEST_MODULE_NAME ": %s - Waiting for the test completion\n",
4605 __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004606
Yaniv Gardi3e327762011-07-27 11:11:04 +03004607 wait_event(test_ctx->wait_q, test_ctx->test_completed);
4608 check_test_result();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004609
Maya Erez8afd564f2011-08-24 15:57:06 +03004610 /*
4611 * Close the channels and zero the is_used flag so that if the modem
4612 * will be reset after the test completion we won't re-open
4613 * the channels
4614 */
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03004615 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
4616 struct test_channel *tch = test_ctx->test_ch_arr[i];
4617
Maya Erez8afd564f2011-08-24 15:57:06 +03004618 if ((!tch) || (!tch->is_used))
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03004619 continue;
Maya Erez8afd564f2011-08-24 15:57:06 +03004620 if ((!tch->ch_ready) ||
4621 (tch->ch_id == SDIO_SMEM) || (!tch->ch->is_packet_mode)) {
4622 tch->is_used = 0;
4623 continue;
4624 }
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03004625 ret = sdio_close(tch->ch);
4626 if (ret) {
4627 pr_err(TEST_MODULE_NAME":%s close channel %s"
4628 " failed\n", __func__, tch->name);
4629 } else {
4630 pr_info(TEST_MODULE_NAME":%s close channel %s"
4631 " success\n", __func__, tch->name);
4632 tch->ch_ready = false;
4633 }
Maya Erez8afd564f2011-08-24 15:57:06 +03004634 tch->is_used = 0;
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03004635 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004636 return 0;
4637}
4638
4639static int set_params_loopback_9k(struct test_channel *tch)
4640{
4641 if (!tch) {
4642 pr_err(TEST_MODULE_NAME ":NULL channel\n");
4643 return -EINVAL;
4644 }
4645 tch->is_used = 1;
4646 tch->test_type = SDIO_TEST_LOOPBACK_CLIENT;
4647 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
4648 tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
4649 tch->config_msg.num_packets = 10000;
4650 tch->config_msg.num_iterations = 1;
4651
4652 tch->packet_length = 512;
4653 if (tch->ch_id == SDIO_RPC)
4654 tch->packet_length = 128;
4655 tch->timer_interval_ms = 0;
4656
4657 return 0;
4658}
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03004659static int set_params_loopback_9k_close(struct test_channel *tch)
4660{
4661 if (!tch) {
4662 pr_err(TEST_MODULE_NAME ":NULL channel\n");
4663 return -EINVAL;
4664 }
4665 tch->is_used = 1;
4666 tch->test_type = SDIO_TEST_CLOSE_CHANNEL;
4667 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
4668 tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
4669 tch->config_msg.num_packets = 5000;
4670 tch->config_msg.num_iterations = 1;
4671 tch->max_burst_size = 10;
4672 switch (tch->ch_id) {
4673 case SDIO_DUN:
4674 case SDIO_RPC:
4675 tch->packet_length = 128; /* max is 2K*/
4676 break;
4677 case SDIO_CIQ:
4678 case SDIO_DIAG:
4679 case SDIO_RMNT:
4680 default:
4681 tch->packet_length = 512; /* max is 4k */
4682 }
4683 tch->timer_interval_ms = 0;
4684 return 0;
4685}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004686static int set_params_a2_perf(struct test_channel *tch)
4687{
4688 if (!tch) {
4689 pr_err(TEST_MODULE_NAME ":NULL channel\n");
4690 return -EINVAL;
4691 }
4692 tch->is_used = 1;
4693 tch->test_type = SDIO_TEST_PERF;
4694 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
4695 tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
Maya Erezbde9df82011-08-02 14:40:00 +03004696 tch->packet_length = MAX_XFER_SIZE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004697 if (tch->ch_id == SDIO_DIAG)
4698 tch->packet_length = 512;
Maya Erezbde9df82011-08-02 14:40:00 +03004699 else if (tch->ch_id == SDIO_DUN)
4700 tch->packet_length = DUN_PACKET_SIZE;
4701 pr_info(TEST_MODULE_NAME ": %s: packet_length=%d", __func__,
4702 tch->packet_length);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004703
4704 tch->config_msg.num_packets = 10000;
4705 tch->config_msg.num_iterations = 1;
4706 tch->random_packet_size = 0;
4707
4708 tch->timer_interval_ms = 0;
4709
4710 return 0;
4711}
4712
Maya Erez53508c12011-08-01 14:04:03 +03004713static int set_params_rtt(struct test_channel *tch)
4714{
4715 if (!tch) {
4716 pr_err(TEST_MODULE_NAME ":NULL channel\n");
4717 return -EINVAL;
4718 }
4719 tch->is_used = 1;
4720 tch->test_type = SDIO_TEST_RTT;
4721 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
4722 tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
4723 tch->packet_length = 32;
4724
4725 tch->config_msg.num_packets = 200;
4726 tch->config_msg.num_iterations = 1;
4727 tch->random_packet_size = 0;
4728
4729 tch->timer_interval_ms = 0;
4730
4731 return 0;
4732}
4733
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004734static int set_params_a2_small_pkts(struct test_channel *tch)
4735{
4736 if (!tch) {
4737 pr_err(TEST_MODULE_NAME ":NULL channel\n");
4738 return -EINVAL;
4739 }
4740 tch->is_used = 1;
4741 tch->test_type = SDIO_TEST_PERF;
4742 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
4743 tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
4744 tch->packet_length = 128;
4745
4746 tch->config_msg.num_packets = 1000000;
4747 tch->config_msg.num_iterations = 1;
4748 tch->random_packet_size = 1;
4749
4750 tch->timer_interval_ms = 0;
4751
4752 return 0;
4753}
4754
Maya Erez8afd564f2011-08-24 15:57:06 +03004755static int set_params_modem_reset(struct test_channel *tch)
4756{
4757 if (!tch) {
4758 pr_err(TEST_MODULE_NAME ":NULL channel\n");
4759 return -EINVAL;
4760 }
4761 tch->is_used = 1;
4762 tch->test_type = SDIO_TEST_MODEM_RESET;
4763 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
4764 tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
4765 tch->packet_length = 512;
4766 if (tch->ch_id == SDIO_RPC)
4767 tch->packet_length = 128;
4768 else if ((tch->ch_id == SDIO_RMNT) || (tch->ch_id == SDIO_DUN))
4769 tch->packet_length = MAX_XFER_SIZE;
4770
4771 tch->config_msg.num_packets = 50000;
4772 tch->config_msg.num_iterations = 1;
4773
4774 tch->timer_interval_ms = 0;
4775
4776 return 0;
4777}
4778
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004779static int set_params_smem_test(struct test_channel *tch)
4780{
4781 if (!tch) {
4782 pr_err(TEST_MODULE_NAME ":NULL channel\n");
4783 return -EINVAL;
4784 }
4785 tch->is_used = 1;
4786 tch->timer_interval_ms = 0;
4787
4788 return 0;
4789}
4790
4791static int set_params_lpm_test(struct test_channel *tch,
4792 enum sdio_test_case_type test,
4793 int timer_interval_ms)
4794{
4795 static int first_time = 1;
4796 if (!tch) {
4797 pr_err(TEST_MODULE_NAME ": %s - NULL channel\n", __func__);
4798 return -EINVAL;
4799 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03004800
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004801 tch->is_used = 1;
4802 tch->test_type = test;
4803 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
4804 tch->config_msg.test_case = test;
Yaniv Gardi3e327762011-07-27 11:11:04 +03004805 tch->config_msg.num_packets = LPM_TEST_NUM_OF_PACKETS;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004806 tch->config_msg.num_iterations = 1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004807 tch->timer_interval_ms = timer_interval_ms;
4808 tch->timeout_ms = 10000;
4809
4810 tch->packet_length = 0;
4811 if (test != SDIO_TEST_LPM_RANDOM) {
4812 init_timer(&tch->timeout_timer);
4813 tch->timeout_timer.data = (unsigned long)tch;
4814 tch->timeout_timer.function = sdio_test_lpm_timeout_handler;
4815 tch->timeout_timer.expires = jiffies +
4816 msecs_to_jiffies(tch->timeout_ms);
4817 add_timer(&tch->timeout_timer);
4818 pr_info(TEST_MODULE_NAME ": %s - Initiated LPM TIMEOUT TIMER."
4819 "set to %d ms\n",
4820 __func__, tch->timeout_ms);
4821 }
4822
4823 if (first_time) {
4824 pr_info(TEST_MODULE_NAME ": %s - wake_lock_init() called\n",
4825 __func__);
4826 wake_lock_init(&test_ctx->wake_lock,
4827 WAKE_LOCK_SUSPEND, TEST_MODULE_NAME);
4828 first_time = 0;
4829 }
4830
4831 pr_info(TEST_MODULE_NAME ": %s - wake_lock() for the TEST is "
Yaniv Gardi3e327762011-07-27 11:11:04 +03004832 "called channel %s. to prevent real sleeping\n",
4833 __func__, tch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004834 wake_lock(&test_ctx->wake_lock);
4835
4836 return 0;
4837}
4838
4839static int set_params_8k_sender_no_lp(struct test_channel *tch)
4840{
4841 if (!tch) {
4842 pr_err(TEST_MODULE_NAME ":NULL channel\n");
4843 return -EINVAL;
4844 }
4845 tch->is_used = 1;
4846 tch->test_type = SDIO_TEST_HOST_SENDER_NO_LP;
4847 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
4848 tch->config_msg.test_case = SDIO_TEST_HOST_SENDER_NO_LP;
4849 tch->config_msg.num_packets = 1000;
4850 tch->config_msg.num_iterations = 1;
4851
4852 tch->packet_length = 512;
4853 if (tch->ch_id == SDIO_RPC)
4854 tch->packet_length = 128;
4855 tch->timer_interval_ms = 0;
4856
4857 return 0;
4858}
4859
Maya Erezf204e692011-08-12 22:00:13 +03004860static void set_pseudo_random_seed(void)
4861{
4862 /* Set the seed accoring to the kernel command parameters if any or
4863 get a random value */
4864 if (seed != 0) {
4865 test_ctx->lpm_pseudo_random_seed = seed;
4866 } else {
4867 test_ctx->lpm_pseudo_random_seed =
4868 (unsigned int)(get_jiffies_64() & 0xFFFF);
4869 test_ctx->lpm_pseudo_random_seed =
4870 pseudo_random_seed(&test_ctx->lpm_pseudo_random_seed);
4871 }
4872
4873 pr_info(TEST_MODULE_NAME ":%s: seed is %u",
4874 __func__, test_ctx->lpm_pseudo_random_seed);
4875}
4876
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03004877/*
4878 for each channel
4879 1. open channel
4880 2. close channel
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03004881*/
Yaniv Gardib4237782011-08-31 20:06:16 +03004882static int close_channel_lpm_test(int channel_num)
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03004883{
4884 int ret = 0;
4885 struct test_channel *tch = NULL;
Yaniv Gardib4237782011-08-31 20:06:16 +03004886 tch = test_ctx->test_ch_arr[channel_num];
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03004887
Yaniv Gardib4237782011-08-31 20:06:16 +03004888 if (!tch->ch_ready) {
4889 ret = sdio_open(tch->name , &tch->ch, tch, notify);
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03004890 if (ret) {
Yaniv Gardib4237782011-08-31 20:06:16 +03004891 pr_err(TEST_MODULE_NAME":%s open channel %s"
4892 " failed\n", __func__, tch->name);
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03004893 return ret;
4894 } else {
Yaniv Gardib4237782011-08-31 20:06:16 +03004895 pr_info(TEST_MODULE_NAME":%s open channel %s"
4896 " success\n", __func__, tch->name);
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03004897 }
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03004898 }
Yaniv Gardib4237782011-08-31 20:06:16 +03004899 ret = sdio_close(tch->ch);
4900 if (ret) {
4901 pr_err(TEST_MODULE_NAME":%s close channel %s"
4902 " failed\n", __func__, tch->name);
4903 return ret;
4904 } else {
4905 pr_info(TEST_MODULE_NAME":%s close channel %s"
4906 " success\n", __func__, tch->name);
4907 tch->ch_ready = false;
4908 }
4909
4910 tch->is_used = 0;
4911
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03004912 return ret;
4913}
4914
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004915/**
4916 * Write File.
4917 *
4918 * @note Trigger the test from user space by:
4919 * echo 1 > /dev/sdio_al_test
4920 *
4921 */
4922ssize_t test_write(struct file *filp, const char __user *buf, size_t size,
4923 loff_t *f_pos)
4924{
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03004925 sdio_al_test_initial_dev_and_chan(test_ctx);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004926
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03004927 if (strict_strtol(buf, 10, &test_ctx->testcase))
4928 return -EINVAL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004929
4930 switch (test_ctx->testcase) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004931 case 98:
4932 pr_info(TEST_MODULE_NAME " set runtime debug on");
4933 test_ctx->runtime_debug = 1;
4934 return size;
4935 case 99:
4936 pr_info(TEST_MODULE_NAME " set runtime debug off");
4937 test_ctx->runtime_debug = 0;
4938 return size;
4939 default:
4940 pr_info(TEST_MODULE_NAME ":Bad Test number = %d.\n",
4941 (int)test_ctx->testcase);
Maya Erez8afd564f2011-08-24 15:57:06 +03004942 return size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004943 }
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03004944
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004945 return size;
4946}
4947
4948/**
4949 * Test Channel Init.
4950 */
4951int test_channel_init(char *name)
4952{
4953 struct test_channel *test_ch;
4954 int ch_id = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004955 int ret;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004956
4957 pr_debug(TEST_MODULE_NAME ":%s.\n", __func__);
4958 pr_info(TEST_MODULE_NAME ": init test cahnnel %s.\n", name);
4959
4960 ch_id = channel_name_to_id(name);
4961 pr_debug(TEST_MODULE_NAME ":id = %d.\n", ch_id);
4962 if (test_ctx->test_ch_arr[ch_id] == NULL) {
4963 test_ch = kzalloc(sizeof(*test_ch), GFP_KERNEL);
4964 if (test_ch == NULL) {
4965 pr_err(TEST_MODULE_NAME ":kzalloc err for allocating "
4966 "test_ch %s.\n",
4967 name);
4968 return -ENOMEM;
4969 }
4970 test_ctx->test_ch_arr[ch_id] = test_ch;
4971
4972 test_ch->ch_id = ch_id;
4973
Maya Erez8afd564f2011-08-24 15:57:06 +03004974 strncpy(test_ch->name, name,
4975 strnlen(name, TEST_CH_NAME_SIZE)-SDIO_TEST_POSTFIX_SIZE);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004976
4977 test_ch->buf_size = MAX_XFER_SIZE;
4978
4979 test_ch->buf = kzalloc(test_ch->buf_size, GFP_KERNEL);
4980 if (test_ch->buf == NULL) {
4981 kfree(test_ch);
4982 test_ctx->test_ch = NULL;
4983 return -ENOMEM;
4984 }
4985
4986 if (test_ch->ch_id == SDIO_SMEM) {
4987 test_ctx->smem_buf = kzalloc(SMEM_MAX_XFER_SIZE,
4988 GFP_KERNEL);
4989 if (test_ctx->smem_buf == NULL) {
4990 pr_err(TEST_MODULE_NAME ":%s: Unable to "
4991 "allocate smem buf\n",
4992 __func__);
4993 kfree(test_ch);
4994 test_ctx->test_ch = NULL;
4995 return -ENOMEM;
4996 }
4997
4998#ifdef CONFIG_MSM_SDIO_SMEM
Maya Erez8afd564f2011-08-24 15:57:06 +03004999 ret = platform_driver_register(&sdio_smem_client_drv);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005000 if (ret) {
5001 pr_err(TEST_MODULE_NAME ":%s: Unable to "
5002 "register sdio smem "
5003 "test client\n",
5004 __func__);
5005 return ret;
5006 }
5007#endif
5008 } else {
5009 test_ch->workqueue =
5010 create_singlethread_workqueue(test_ch->name);
5011 test_ch->test_work.test_ch = test_ch;
5012 INIT_WORK(&test_ch->test_work.work, worker);
5013
5014 init_waitqueue_head(&test_ch->wait_q);
5015 }
5016 } else {
Maya Erez8afd564f2011-08-24 15:57:06 +03005017 test_ch = test_ctx->test_ch_arr[ch_id];
5018 pr_info(TEST_MODULE_NAME ":%s: ch %s was detected again\n",
5019 __func__, test_ch->name);
5020 test_ch->card_removed = 0;
5021 if ((test_ch->is_used) &&
5022 (test_ch->test_type == SDIO_TEST_MODEM_RESET)) {
5023 if (test_ch->ch_id == SDIO_SMEM) {
5024 test_ctx->smem_pdev.name = "SDIO_SMEM";
5025 test_ctx->smem_pdev.dev.release =
5026 default_sdio_al_test_release;
5027 platform_device_register(&test_ctx->smem_pdev);
5028 } else {
5029 test_ch->ch_ready = true;
5030 ret = sdio_open(test_ch->name , &test_ch->ch,
5031 test_ch, notify);
5032 if (ret) {
5033 pr_info(TEST_MODULE_NAME
5034 ":openning channel %s failed\n",
5035 test_ch->name);
5036 test_ch->ch_ready = false;
5037 return 0;
5038 }
5039 ret = sdio_test_find_dev(test_ch);
5040
5041 if (ret) {
5042 pr_err(TEST_MODULE_NAME ": %s - "
5043 "sdio_test_find_dev() returned "
5044 "with error", __func__);
5045 return -ENODEV;
5046 }
5047
5048 test_ch->sdio_al_device =
5049 test_ch->ch->sdio_al_dev;
5050 }
5051 atomic_set(&test_ch->card_detected_event, 1);
5052 wake_up(&test_ch->wait_q);
5053 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005054 }
5055
5056 return 0;
5057}
5058
Maya Erez8afd564f2011-08-24 15:57:06 +03005059static int sdio_test_channel_probe(struct platform_device *pdev)
5060{
5061 if (!pdev)
5062 return -EIO;
5063 return test_channel_init((char *)pdev->name);
5064}
5065
5066static int sdio_test_channel_remove(struct platform_device *pdev)
5067{
5068 int ch_id;
5069
5070 if (!pdev)
5071 return -EIO;
5072
5073 ch_id = channel_name_to_id((char *)pdev->name);
5074 if (test_ctx->test_ch_arr[ch_id] == NULL)
5075 return 0;
5076
5077 pr_info(TEST_MODULE_NAME "%s: remove ch %s\n",
5078 __func__, test_ctx->test_ch_arr[ch_id]->name);
5079 test_ctx->test_ch_arr[ch_id]->ch_ready = 0;
5080 test_ctx->test_ch_arr[ch_id]->card_removed = 1;
5081
5082 return 0;
5083
5084}
5085
5086static struct platform_driver sdio_rpc_drv = {
5087 .probe = sdio_test_channel_probe,
5088 .remove = sdio_test_channel_remove,
5089 .driver = {
5090 .name = "SDIO_RPC_TEST",
5091 .owner = THIS_MODULE,
5092 },
5093};
5094
5095static struct platform_driver sdio_qmi_drv = {
5096 .probe = sdio_test_channel_probe,
5097 .remove = sdio_test_channel_remove,
5098 .driver = {
5099 .name = "SDIO_QMI_TEST",
5100 .owner = THIS_MODULE,
5101 },
5102};
5103
5104static struct platform_driver sdio_diag_drv = {
5105 .probe = sdio_test_channel_probe,
5106 .remove = sdio_test_channel_remove,
5107 .driver = {
5108 .name = "SDIO_DIAG_TEST",
5109 .owner = THIS_MODULE,
5110 },
5111};
5112
5113static struct platform_driver sdio_smem_drv = {
5114 .probe = sdio_test_channel_probe,
5115 .remove = sdio_test_channel_remove,
5116 .driver = {
5117 .name = "SDIO_SMEM_TEST",
5118 .owner = THIS_MODULE,
5119 },
5120};
5121
5122static struct platform_driver sdio_rmnt_drv = {
5123 .probe = sdio_test_channel_probe,
5124 .remove = sdio_test_channel_remove,
5125 .driver = {
5126 .name = "SDIO_RMNT_TEST",
5127 .owner = THIS_MODULE,
5128 },
5129};
5130
5131static struct platform_driver sdio_dun_drv = {
5132 .probe = sdio_test_channel_probe,
5133 .remove = sdio_test_channel_remove,
5134 .driver = {
5135 .name = "SDIO_DUN_TEST",
5136 .owner = THIS_MODULE,
5137 },
5138};
5139
5140static struct platform_driver sdio_ciq_drv = {
5141 .probe = sdio_test_channel_probe,
5142 .remove = sdio_test_channel_remove,
5143 .driver = {
5144 .name = "SDIO_CIQ_TEST",
5145 .owner = THIS_MODULE,
5146 },
5147};
5148
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005149static struct class *test_class;
5150
5151const struct file_operations test_fops = {
5152 .owner = THIS_MODULE,
5153 .write = test_write,
5154};
5155
5156/**
5157 * Module Init.
5158 */
5159static int __init test_init(void)
5160{
5161 int ret;
5162
5163 pr_debug(TEST_MODULE_NAME ":test_init.\n");
5164
Yaniv Gardi3e327762011-07-27 11:11:04 +03005165 test_ctx = kzalloc(sizeof(struct test_context), GFP_KERNEL);
5166
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005167 if (test_ctx == NULL) {
5168 pr_err(TEST_MODULE_NAME ":kzalloc err.\n");
5169 return -ENOMEM;
5170 }
5171 test_ctx->test_ch = NULL;
5172 test_ctx->signature = TEST_SIGNATURE;
5173
5174 test_ctx->name = "UNKNOWN";
5175
5176 init_waitqueue_head(&test_ctx->wait_q);
5177
5178#ifdef CONFIG_DEBUG_FS
5179 sdio_al_test_debugfs_init();
5180#endif
5181
5182 test_class = class_create(THIS_MODULE, TEST_MODULE_NAME);
5183
5184 ret = alloc_chrdev_region(&test_ctx->dev_num, 0, 1, TEST_MODULE_NAME);
5185 if (ret) {
5186 pr_err(TEST_MODULE_NAME "alloc_chrdev_region err.\n");
5187 return -ENODEV;
5188 }
5189
5190 test_ctx->dev = device_create(test_class, NULL, test_ctx->dev_num,
5191 test_ctx, TEST_MODULE_NAME);
5192 if (IS_ERR(test_ctx->dev)) {
5193 pr_err(TEST_MODULE_NAME ":device_create err.\n");
5194 return -ENODEV;
5195 }
5196
5197 test_ctx->cdev = cdev_alloc();
5198 if (test_ctx->cdev == NULL) {
5199 pr_err(TEST_MODULE_NAME ":cdev_alloc err.\n");
5200 return -ENODEV;
5201 }
5202 cdev_init(test_ctx->cdev, &test_fops);
5203 test_ctx->cdev->owner = THIS_MODULE;
5204
5205 ret = cdev_add(test_ctx->cdev, test_ctx->dev_num, 1);
5206 if (ret)
5207 pr_err(TEST_MODULE_NAME ":cdev_add err=%d\n", -ret);
5208 else
5209 pr_debug(TEST_MODULE_NAME ":SDIO-AL-Test init OK..\n");
5210
Maya Erez8afd564f2011-08-24 15:57:06 +03005211 platform_driver_register(&sdio_rpc_drv);
5212 platform_driver_register(&sdio_qmi_drv);
5213 platform_driver_register(&sdio_diag_drv);
5214 platform_driver_register(&sdio_smem_drv);
5215 platform_driver_register(&sdio_rmnt_drv);
5216 platform_driver_register(&sdio_dun_drv);
5217 platform_driver_register(&sdio_ciq_drv);
5218
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005219 return ret;
5220}
5221
5222/**
5223 * Module Exit.
5224 */
5225static void __exit test_exit(void)
5226{
5227 int i;
5228
5229 pr_debug(TEST_MODULE_NAME ":test_exit.\n");
5230
5231 test_ctx->exit_flag = true;
5232
5233 msleep(100); /* allow gracefully exit of the worker thread */
5234
5235 cdev_del(test_ctx->cdev);
5236 device_destroy(test_class, test_ctx->dev_num);
5237 unregister_chrdev_region(test_ctx->dev_num, 1);
5238
Maya Erez8afd564f2011-08-24 15:57:06 +03005239 platform_driver_unregister(&sdio_rpc_drv);
5240 platform_driver_unregister(&sdio_qmi_drv);
5241 platform_driver_unregister(&sdio_diag_drv);
5242 platform_driver_unregister(&sdio_smem_drv);
5243 platform_driver_unregister(&sdio_rmnt_drv);
5244 platform_driver_unregister(&sdio_dun_drv);
5245 platform_driver_unregister(&sdio_ciq_drv);
5246
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005247 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
5248 struct test_channel *tch = test_ctx->test_ch_arr[i];
5249 if (!tch)
5250 continue;
5251 kfree(tch->buf);
5252 kfree(tch);
5253 }
5254
5255#ifdef CONFIG_DEBUG_FS
5256 sdio_al_test_debugfs_cleanup();
5257#endif
5258
5259 kfree(test_ctx);
5260
5261 pr_debug(TEST_MODULE_NAME ":test_exit complete.\n");
5262}
5263
5264module_init(test_init);
5265module_exit(test_exit);
5266
5267MODULE_LICENSE("GPL v2");
5268MODULE_DESCRIPTION("SDIO_AL Test");
5269MODULE_AUTHOR("Amir Samuelov <amirs@codeaurora.org>");
5270
5271