blob: 2c9f675e201a4df0322d735affa4f4f8cbdda8be [file] [log] [blame]
Duy Truong790f06d2013-02-13 16:38:12 -08001/* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13/*
14 * SDIO-Abstraction-Layer Test Module.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/device.h>
20#include <linux/workqueue.h>
21#include <linux/fs.h>
22#include <linux/cdev.h>
23#include <linux/sched.h>
24#include <linux/wait.h>
25#include <linux/delay.h>
26#include <linux/slab.h>
27#include <linux/random.h>
28#include <linux/platform_device.h>
29#include <mach/sdio_smem.h>
30#include <linux/wakelock.h>
Yaniv Gardifa8b71e2011-09-06 14:00:55 +030031#include <linux/uaccess.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070032
Alhad Purnapatred0d12e72011-10-26 14:04:42 -070033#include "sdio_al_private.h"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070034#include <linux/debugfs.h>
35
36#include <linux/kthread.h>
37enum lpm_test_msg_type {
Yaniv Gardi3e327762011-07-27 11:11:04 +030038 LPM_NO_MSG, /* 0 */
39 LPM_MSG_SEND, /* 1 */
40 LPM_MSG_REC, /* 2 */
41 LPM_SLEEP, /* 3 */
42 LPM_WAKEUP, /* 4 */
43 LPM_NOTIFY /* 5 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070044};
45
46#define LPM_NO_MSG_NAME "LPM No Event"
47#define LPM_MSG_SEND_NAME "LPM Send Msg Event"
48#define LPM_MSG_REC_NAME "LPM Receive Msg Event"
49#define LPM_SLEEP_NAME "LPM Sleep Event"
50#define LPM_WAKEUP_NAME "LPM Wakeup Event"
51
52/** Module name string */
53#define TEST_MODULE_NAME "sdio_al_test"
54
55#define TEST_SIGNATURE 0x12345678
56#define TEST_CONFIG_SIGNATURE 0xBEEFCAFE
57
58#define MAX_XFER_SIZE (16*1024)
59#define SMEM_MAX_XFER_SIZE 0xBC000
60#define A2_MIN_PACKET_SIZE 5
Venkat Gopalakrishnandcc6aac2011-08-29 18:57:11 -070061#define RMNT_PACKET_SIZE (4*1024)
Maya Erezbde9df82011-08-02 14:40:00 +030062#define DUN_PACKET_SIZE (2*1024)
Maya Erez241eb922011-10-23 10:51:26 +020063#define CSVT_PACKET_SIZE 1700
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070064
65#define TEST_DBG(x...) if (test_ctx->runtime_debug) pr_info(x)
66
67#define LPM_TEST_NUM_OF_PACKETS 100
Yaniv Gardi3e327762011-07-27 11:11:04 +030068#define LPM_MAX_OPEN_CHAN_PER_DEV 4
69#define LPM_ARRAY_SIZE (7*LPM_TEST_NUM_OF_PACKETS*LPM_MAX_OPEN_CHAN_PER_DEV)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070070#define SDIO_LPM_TEST "sdio_lpm_test_reading_task"
71#define LPM_TEST_CONFIG_SIGNATURE 0xDEADBABE
Yaniv Gardi3e327762011-07-27 11:11:04 +030072#define LPM_MSG_NAME_SIZE 20
Yaniv Gardifa8b71e2011-09-06 14:00:55 +030073#define MAX_STR_SIZE 10
Maya Erez241eb922011-10-23 10:51:26 +020074#define MAX_AVG_RTT_TIME_USEC 2500
75#define SDIO_RMNT_RTT_PACKET_SIZE 32
76#define SDIO_CSVT_RTT_PACKET_SIZE 1900
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070077
Maya Erez53508c12011-08-01 14:04:03 +030078#define A2_HEADER_OVERHEAD 8
79
Venkat Gopalakrishnandcc6aac2011-08-29 18:57:11 -070080enum rx_process_state {
81 RX_PROCESS_PACKET_INIT,
82 RX_PROCESS_A2_HEADER,
83 RX_PROCESS_PACKET_DATA,
84};
85
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070086enum sdio_test_case_type {
87 SDIO_TEST_LOOPBACK_HOST,
88 SDIO_TEST_LOOPBACK_CLIENT,
89 SDIO_TEST_LPM_HOST_WAKER,
90 SDIO_TEST_LPM_CLIENT_WAKER,
91 SDIO_TEST_LPM_RANDOM,
92 SDIO_TEST_HOST_SENDER_NO_LP,
Konstantin Dorfman65ac9222011-08-18 16:30:17 +030093 SDIO_TEST_CLOSE_CHANNEL,
Venkat Gopalakrishnandcc6aac2011-08-29 18:57:11 -070094 SDIO_TEST_A2_VALIDATION,
Maya Erez53508c12011-08-01 14:04:03 +030095 /* The following tests are not part of the 9k tests and should be
96 * kept last in case new tests are added
97 */
98 SDIO_TEST_PERF,
99 SDIO_TEST_RTT,
Maya Erez8afd564f2011-08-24 15:57:06 +0300100 SDIO_TEST_MODEM_RESET,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700101};
102
103struct lpm_task {
104 struct task_struct *lpm_task;
105 const char *task_name;
106};
107
108struct lpm_entry_type {
109 enum lpm_test_msg_type msg_type;
Yaniv Gardi3e327762011-07-27 11:11:04 +0300110 char msg_name[LPM_MSG_NAME_SIZE];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700111 u32 counter;
112 u32 current_ms;
Yaniv Gardi3e327762011-07-27 11:11:04 +0300113 u32 read_avail_mask;
114 char chan_name[CHANNEL_NAME_SIZE];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700115};
116
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700117struct lpm_msg {
118 u32 signature;
119 u32 counter;
120 u32 reserve1;
121 u32 reserve2;
122};
123
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700124struct test_config_msg {
125 u32 signature;
126 u32 test_case;
127 u32 test_param;
128 u32 num_packets;
129 u32 num_iterations;
130};
131
132struct test_result_msg {
133 u32 signature;
134 u32 is_successful;
135};
136
137struct test_work {
138 struct work_struct work;
139 struct test_channel *test_ch;
140};
141
142enum sdio_channels_ids {
143 SDIO_RPC,
144 SDIO_QMI,
145 SDIO_RMNT,
146 SDIO_DIAG,
147 SDIO_DUN,
148 SDIO_SMEM,
Maya Erez241eb922011-10-23 10:51:26 +0200149 SDIO_CSVT,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700150 SDIO_MAX_CHANNELS
151};
152
153enum sdio_test_results {
154 TEST_NO_RESULT,
155 TEST_FAILED,
156 TEST_PASSED
157};
158
159enum sdio_lpm_vote_state {
160 SDIO_NO_VOTE,
161 SDIO_VOTE_FOR_SLEEP,
162 SDIO_VOTE_AGAINST_SLEEP
163};
164
Yaniv Gardi3e327762011-07-27 11:11:04 +0300165struct sdio_test_device {
166 int open_channels_counter_to_recv;
167 int open_channels_counter_to_send;
168 struct lpm_entry_type *lpm_arr;
169 int array_size;
170 void *sdio_al_device;
171 spinlock_t lpm_array_lock;
172 unsigned long lpm_array_lock_flags;
173 u32 next_avail_entry_in_array;
174 struct lpm_task lpm_test_task;
175 u32 next_mask_id;
176 u32 read_avail_mask;
177 int modem_result_per_dev;
178 int final_result_per_dev;
179};
180
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700181struct test_channel {
182 struct sdio_channel *ch;
183
184 char name[CHANNEL_NAME_SIZE];
185 int ch_id;
186
Yaniv Gardi3e327762011-07-27 11:11:04 +0300187 struct sdio_test_device *test_device;
188
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700189 u32 *buf;
190 u32 buf_size;
191
192 struct workqueue_struct *workqueue;
193 struct test_work test_work;
194
195 u32 rx_bytes;
196 u32 tx_bytes;
197
198 wait_queue_head_t wait_q;
199 atomic_t rx_notify_count;
200 atomic_t tx_notify_count;
201 atomic_t any_notify_count;
202 atomic_t wakeup_client;
Maya Erez8afd564f2011-08-24 15:57:06 +0300203 atomic_t card_detected_event;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700204
205 int wait_counter;
206
207 int is_used;
208 int test_type;
209 int ch_ready;
210
211 struct test_config_msg config_msg;
212
213 int test_completed;
214 int test_result;
215 struct timer_list timer;
216 int timer_interval_ms;
217
218 struct timer_list timeout_timer;
219 int timeout_ms;
220 void *sdio_al_device;
221 int is_ok_to_sleep;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700222 unsigned int packet_length;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700223 int random_packet_size;
Yaniv Gardi3e327762011-07-27 11:11:04 +0300224 int next_index_in_sent_msg_per_chan;
225 int channel_mask_id;
226 int modem_result_per_chan;
227 int notify_counter_per_chan;
Konstantin Dorfman65ac9222011-08-18 16:30:17 +0300228 int max_burst_size; /* number of writes before close/open */
Maya Erez8afd564f2011-08-24 15:57:06 +0300229 int card_removed;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700230};
231
232struct sdio_al_test_debug {
233 u32 dun_throughput;
234 u32 rmnt_throughput;
235 struct dentry *debug_root;
236 struct dentry *debug_test_result;
237 struct dentry *debug_dun_throughput;
238 struct dentry *debug_rmnt_throughput;
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300239 struct dentry *rpc_sender_test;
240 struct dentry *rpc_qmi_diag_sender_test;
241 struct dentry *smem_test;
242 struct dentry *smem_rpc_test;
Venkat Gopalakrishnandcc6aac2011-08-29 18:57:11 -0700243 struct dentry *rmnet_a2_validation_test;
244 struct dentry *dun_a2_validation_test;
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300245 struct dentry *rmnet_a2_perf_test;
246 struct dentry *dun_a2_perf_test;
Maya Erez241eb922011-10-23 10:51:26 +0200247 struct dentry *csvt_a2_perf_test;
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300248 struct dentry *rmnet_dun_a2_perf_test;
249 struct dentry *rpc_sender_rmnet_a2_perf_test;
250 struct dentry *all_channels_test;
251 struct dentry *host_sender_no_lp_diag_test;
Venkat Gopalakrishnanc4093f92012-01-13 17:57:31 -0800252 struct dentry *host_sender_no_lp_diag_rpc_test;
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300253 struct dentry *rmnet_small_packets_test;
254 struct dentry *rmnet_rtt_test;
Maya Erez241eb922011-10-23 10:51:26 +0200255 struct dentry *csvt_rtt_test;
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300256 struct dentry *modem_reset_rpc_test;
257 struct dentry *modem_reset_rmnet_test;
258 struct dentry *modem_reset_channels_4bit_dev_test;
259 struct dentry *modem_reset_channels_8bit_dev_test;
260 struct dentry *modem_reset_all_channels_test;
Maya Erezefafaa82011-09-21 12:41:28 +0300261 struct dentry *open_close_test;
Maya Ereze05fc4d2011-09-11 14:18:43 +0300262 struct dentry *open_close_dun_rmnet_test;
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300263 struct dentry *close_chan_lpm_test;
264 struct dentry *lpm_test_client_wakes_host_test;
265 struct dentry *lpm_test_host_wakes_client_test;
266 struct dentry *lpm_test_random_single_channel_test;
267 struct dentry *lpm_test_random_multi_channel_test;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700268};
269
270struct test_context {
271 dev_t dev_num;
272 struct device *dev;
273 struct cdev *cdev;
Yaniv Gardi3e327762011-07-27 11:11:04 +0300274 int number_of_active_devices;
275 int max_number_of_devices;
276
277 struct sdio_test_device test_dev_arr[MAX_NUM_OF_SDIO_DEVICES];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700278
279 struct test_channel *test_ch;
280
281 struct test_channel *test_ch_arr[SDIO_MAX_CHANNELS];
282
283 long testcase;
284
285 const char *name;
286
287 int exit_flag;
288
289 u32 signature;
290
291 int runtime_debug;
292
Maya Erezefafaa82011-09-21 12:41:28 +0300293 struct platform_device *smem_pdev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700294 struct sdio_smem_client *sdio_smem;
295 int smem_was_init;
296 u8 *smem_buf;
Maya Erezefafaa82011-09-21 12:41:28 +0300297 uint32_t smem_counter;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700298
Venkat Gopalakrishnan3ebdd432011-11-08 19:53:43 -0800299 struct platform_device *csvt_app_pdev;
Maya Erezd7a5acf2011-10-05 13:20:28 +0200300
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700301 wait_queue_head_t wait_q;
302 int test_completed;
303 int test_result;
304 struct sdio_al_test_debug debug;
305
306 struct wake_lock wake_lock;
Maya Erezf204e692011-08-12 22:00:13 +0300307
308 unsigned int lpm_pseudo_random_seed;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700309};
310
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300311/* FORWARD DECLARATIONS */
312static int set_params_loopback_9k(struct test_channel *tch);
313static int set_params_smem_test(struct test_channel *tch);
Venkat Gopalakrishnandcc6aac2011-08-29 18:57:11 -0700314static int set_params_a2_validation(struct test_channel *tch);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300315static int set_params_a2_perf(struct test_channel *tch);
316static int set_params_8k_sender_no_lp(struct test_channel *tch);
317static int set_params_a2_small_pkts(struct test_channel *tch);
318static int set_params_rtt(struct test_channel *tch);
319static int set_params_loopback_9k_close(struct test_channel *tch);
Yaniv Gardib4237782011-08-31 20:06:16 +0300320static int close_channel_lpm_test(int channel_num);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300321static int set_params_lpm_test(struct test_channel *tch,
322 enum sdio_test_case_type test,
323 int timer_interval_ms);
324static void set_pseudo_random_seed(void);
325static int set_params_modem_reset(struct test_channel *tch);
326static int test_start(void);
Yaniv Gardi9263c212011-08-31 20:37:45 +0300327static void rx_cleanup(struct test_channel *test_ch, int *rx_packet_count);
328static void sdio_al_test_cleanup_channels(void);
Maya Erezefafaa82011-09-21 12:41:28 +0300329static void notify(void *priv, unsigned channel_event);
330#ifdef CONFIG_MSM_SDIO_SMEM
331static int sdio_smem_open(struct sdio_smem_client *sdio_smem);
332#endif
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300333
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700334/*
335 * Seed for pseudo random time sleeping in Random LPM test.
336 * If not set, current time in jiffies is used.
337 */
338static unsigned int seed;
339module_param(seed, int, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700340static struct test_context *test_ctx;
341
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300342static void sdio_al_test_initial_dev_and_chan(struct test_context *test_ctx)
343{
Yaniv Gardi9263c212011-08-31 20:37:45 +0300344 int i = 0;
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300345
Maya Erez241eb922011-10-23 10:51:26 +0200346 if (!test_ctx) {
347 pr_err(TEST_MODULE_NAME ":%s - test_ctx is NULL.\n", __func__);
348 return;
349 }
350
Yaniv Gardi9263c212011-08-31 20:37:45 +0300351 for (i = 0 ; i < MAX_NUM_OF_SDIO_DEVICES ; ++i)
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300352 test_ctx->test_dev_arr[i].sdio_al_device = NULL;
353
Yaniv Gardi9263c212011-08-31 20:37:45 +0300354 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300355 struct test_channel *tch = test_ctx->test_ch_arr[i];
356 if (!tch)
357 continue;
358 tch->is_used = 0;
359 }
Yaniv Gardi9263c212011-08-31 20:37:45 +0300360
361 sdio_al_test_cleanup_channels();
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300362}
363
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700364#ifdef CONFIG_DEBUG_FS
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300365
366static int message_repeat;
367
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300368static int sdio_al_test_extract_number(const char __user *buf,
369 size_t count)
370{
371 int ret = 0;
372 int number = -1;
373 char local_buf[MAX_STR_SIZE] = {0};
374 char *start = NULL;
375
376 if (count > MAX_STR_SIZE) {
377 pr_err(TEST_MODULE_NAME ": %s - MAX_STR_SIZE(%d) < count(%d). "
378 "Please choose smaller number\n",
379 __func__, MAX_STR_SIZE, (int)count);
380 return -EINVAL;
381 }
382
383 if (copy_from_user(local_buf, buf, count)) {
384 pr_err(TEST_MODULE_NAME ": %s - copy_from_user() failed\n",
385 __func__);
386 return -EINVAL;
387 }
388
389 /* adding null termination to the string */
390 local_buf[count] = '\0';
391
392 /* stripping leading and trailing white spaces */
393 start = strstrip(local_buf);
394
395 ret = kstrtoint(start, 10, &number);
396
397 if (ret) {
398 pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
399 __func__);
400 return ret;
401 }
402
403 return number;
404}
405
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300406static int sdio_al_test_open(struct inode *inode, struct file *file)
407{
408 file->private_data = inode->i_private;
409 message_repeat = 1;
410 return 0;
411}
412
Yaniv Gardi9263c212011-08-31 20:37:45 +0300413static void sdio_al_test_cleanup_channels(void)
414{
415 int channel_num;
416 int dummy = 0;
417
418 for (channel_num = 0 ; channel_num < SDIO_MAX_CHANNELS ;
419 ++channel_num) {
420 if (channel_num == SDIO_SMEM)
421 continue;
422
423 rx_cleanup(test_ctx->test_ch_arr[channel_num], &dummy);
424 }
425
426 return;
427}
428
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300429/* RPC SENDER TEST */
430static ssize_t rpc_sender_test_write(struct file *file,
431 const char __user *buf,
432 size_t count,
433 loff_t *ppos)
434{
435 int ret = 0;
436 int i = 0;
437 int number = -1;
438
439 pr_info(TEST_MODULE_NAME "-- RPC SENDER TEST --\n");
440
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300441 number = sdio_al_test_extract_number(buf, count);
442
443 if (number < 0) {
444 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
445 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300446 return count;
447 }
448
449 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300450 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
451 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300452
453 sdio_al_test_initial_dev_and_chan(test_ctx);
454
455 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
456
457 ret = test_start();
458
459 if (ret)
460 break;
461 }
462
463 return count;
464}
465
466static ssize_t rpc_sender_test_read(struct file *file,
467 char __user *buffer,
468 size_t count,
469 loff_t *offset)
470{
471 memset((void *)buffer, 0, count);
472
473 snprintf(buffer, count,
474 "\nRPC_SENDER_TEST\n"
475 "===============\n"
476 "Description:\n"
477 "TBD\n");
478
479 if (message_repeat == 1) {
480 message_repeat = 0;
481 return strnlen(buffer, count);
482 } else {
483 return 0;
484 }
485}
486
487const struct file_operations rpc_sender_test_ops = {
488 .open = sdio_al_test_open,
489 .write = rpc_sender_test_write,
490 .read = rpc_sender_test_read,
491};
492
493/* RPC, QMI & DIAG SENDER TEST */
494static ssize_t rpc_qmi_diag_sender_test_write(struct file *file,
495 const char __user *buf,
496 size_t count,
497 loff_t *ppos)
498{
499 int ret = 0;
500 int i = 0;
501 int number = -1;
502
503 pr_info(TEST_MODULE_NAME "-- RPC, QMI AND DIAG SENDER TEST --\n");
504
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300505 number = sdio_al_test_extract_number(buf, count);
506
507 if (number < 0) {
508 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
509 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300510 return count;
511 }
512
513 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300514 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
515 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300516
517 sdio_al_test_initial_dev_and_chan(test_ctx);
518
519 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
520 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_QMI]);
521 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_DIAG]);
522
523 ret = test_start();
524
525 if (ret)
526 break;
527 }
528
529 return count;
530}
531
532static ssize_t rpc_qmi_diag_sender_test_read(struct file *file,
533 char __user
534 *buffer, size_t count,
535 loff_t *offset)
536{
537 memset((void *)buffer, 0, count);
538
539 snprintf(buffer, count,
540 "\nRPC_QMI_DIAG_SENDER_TEST\n"
541 "========================\n"
542 "Description:\n"
543 "TBD\n");
544
545
546 if (message_repeat == 1) {
547 message_repeat = 0;
548 return strnlen(buffer, count);
549 } else {
550 return 0;
551 }
552}
553
554const struct file_operations rpc_qmi_diag_sender_test_ops = {
555 .open = sdio_al_test_open,
556 .write = rpc_qmi_diag_sender_test_write,
557 .read = rpc_qmi_diag_sender_test_read,
558};
559
560/* SMEM TEST */
561static ssize_t smem_test_write(struct file *file,
562 const char __user *buf,
563 size_t count,
564 loff_t *ppos)
565{
566 int ret = 0;
567 int i = 0;
568 int number = -1;
569
570 pr_info(TEST_MODULE_NAME "-- SMEM TEST --\n");
571
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300572 number = sdio_al_test_extract_number(buf, count);
573
574 if (number < 0) {
575 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
576 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300577 return count;
578 }
579
580 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300581 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
582 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300583
584 sdio_al_test_initial_dev_and_chan(test_ctx);
585
586 set_params_smem_test(test_ctx->test_ch_arr[SDIO_SMEM]);
587
588 ret = test_start();
589
590 if (ret)
591 break;
592 }
593
594 return count;
595}
596
597static ssize_t smem_test_read(struct file *file,
598 char __user *buffer,
599 size_t count,
600 loff_t *offset)
601{
602 memset((void *)buffer, 0, count);
603
604 snprintf(buffer, count,
605 "\nSMEM_TEST\n"
606 "=========\n"
607 "Description:\n"
608 "TBD\n");
609
610 if (message_repeat == 1) {
611 message_repeat = 0;
612 return strnlen(buffer, count);
613 } else {
614 return 0;
615 }
616}
617
618const struct file_operations smem_test_ops = {
619 .open = sdio_al_test_open,
620 .write = smem_test_write,
621 .read = smem_test_read,
622};
623
624/* SMEM & RPC TEST */
625static ssize_t smem_rpc_test_write(struct file *file,
626 const char __user *buf,
627 size_t count,
628 loff_t *ppos)
629{
630 int ret = 0;
631 int i = 0;
632 int number = -1;
633
634 pr_info(TEST_MODULE_NAME "-- SMEM AND RPC TEST --\n");
635
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300636 number = sdio_al_test_extract_number(buf, count);
637
638 if (number < 0) {
639 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
640 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300641 return count;
642 }
643
644 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300645 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
646 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300647
648 sdio_al_test_initial_dev_and_chan(test_ctx);
649
650 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
651 set_params_smem_test(test_ctx->test_ch_arr[SDIO_SMEM]);
652
653 ret = test_start();
654
655 if (ret)
656 break;
657 }
658
659 return count;
660}
661
662static ssize_t smem_rpc_test_read(struct file *file,
663 char __user *buffer,
664 size_t count,
665 loff_t *offset)
666{
667 memset((void *)buffer, 0, count);
668
669 snprintf(buffer, count,
670 "\nSMEM_RPC_TEST\n"
671 "=============\n"
672 "Description:\n"
673 "TBD\n");
674
675 if (message_repeat == 1) {
676 message_repeat = 0;
677 return strnlen(buffer, count);
678 } else {
679 return 0;
680 }
681}
682
683const struct file_operations smem_rpc_test_ops = {
684 .open = sdio_al_test_open,
685 .write = smem_rpc_test_write,
686 .read = smem_rpc_test_read,
687};
688
Venkat Gopalakrishnandcc6aac2011-08-29 18:57:11 -0700689/* RMNET A2 VALIDATION TEST */
690static ssize_t rmnet_a2_validation_test_write(struct file *file,
691 const char __user *buf,
692 size_t count,
693 loff_t *ppos)
694{
695 int ret = 0;
696 int i = 0;
697 int number = -1;
698
699 pr_info(TEST_MODULE_NAME "-- RMNET A2 VALIDATION TEST --\n");
700
701 number = sdio_al_test_extract_number(buf, count);
702
703 if (number < 0) {
704 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
705 "failed. number = %d\n", __func__, number);
706 return count;
707 }
708
709 for (i = 0 ; i < number ; ++i) {
710 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
711 pr_info(TEST_MODULE_NAME " ===================");
712
713 sdio_al_test_initial_dev_and_chan(test_ctx);
714
715 set_params_a2_validation(test_ctx->test_ch_arr[SDIO_RMNT]);
716
717 ret = test_start();
718
719 if (ret)
720 break;
721 }
722
723 return count;
724}
725
726static ssize_t rmnet_a2_validation_test_read(struct file *file,
727 char __user *buffer,
728 size_t count,
729 loff_t *offset)
730{
731 memset((void *)buffer, 0, count);
732
733 snprintf(buffer, count,
734 "\nRMNET_A2_VALIDATION_TEST\n"
735 "=========================\n"
736 "Description:\n"
737 "In this test, the HOST sends multiple packets to the\n"
738 "CLIENT and validates the packets loop backed from A2\n"
739 "for the RMNET channel.\n\n"
740 "END OF DESCRIPTION\n");
741
742 if (message_repeat == 1) {
743 message_repeat = 0;
744 return strnlen(buffer, count);
745 } else {
746 return 0;
747 }
748}
749
750const struct file_operations rmnet_a2_validation_test_ops = {
751 .open = sdio_al_test_open,
752 .write = rmnet_a2_validation_test_write,
753 .read = rmnet_a2_validation_test_read,
754};
755
756/* DUN A2 VALIDATION TEST */
757static ssize_t dun_a2_validation_test_write(struct file *file,
758 const char __user *buf,
759 size_t count,
760 loff_t *ppos)
761{
762 int ret = 0;
763 int i = 0;
764 int number = -1;
765
766 pr_info(TEST_MODULE_NAME "-- DUN A2 VALIDATION TEST --\n");
767
768 number = sdio_al_test_extract_number(buf, count);
769
770 if (number < 0) {
771 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
772 "failed. number = %d\n", __func__, number);
773 return count;
774 }
775
776 for (i = 0 ; i < number ; ++i) {
777 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
778 pr_info(TEST_MODULE_NAME " ===================");
779
780 sdio_al_test_initial_dev_and_chan(test_ctx);
781
782 set_params_a2_validation(test_ctx->test_ch_arr[SDIO_DUN]);
783
784 ret = test_start();
785
786 if (ret)
787 break;
788 }
789
790 return count;
791}
792
793static ssize_t dun_a2_validation_test_read(struct file *file,
794 char __user *buffer,
795 size_t count,
796 loff_t *offset)
797{
798 memset((void *)buffer, 0, count);
799
800 snprintf(buffer, count,
801 "\nDUN_A2_VALIDATION_TEST\n"
802 "=========================\n"
803 "Description:\n"
804 "In this test, the HOST sends multiple packets to the\n"
805 "CLIENT and validates the packets loop backed from A2\n"
806 "for the DUN channel.\n\n"
807 "END OF DESCRIPTION\n");
808
809 if (message_repeat == 1) {
810 message_repeat = 0;
811 return strnlen(buffer, count);
812 } else {
813 return 0;
814 }
815}
816
817const struct file_operations dun_a2_validation_test_ops = {
818 .open = sdio_al_test_open,
819 .write = dun_a2_validation_test_write,
820 .read = dun_a2_validation_test_read,
821};
822
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300823/* RMNET A2 PERFORMANCE TEST */
824static ssize_t rmnet_a2_perf_test_write(struct file *file,
825 const char __user *buf,
826 size_t count,
827 loff_t *ppos)
828{
829 int ret = 0;
830 int i = 0;
831 int number = -1;
832
833 pr_info(TEST_MODULE_NAME "-- RMNET A2 PERFORMANCE TEST --\n");
834
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300835 number = sdio_al_test_extract_number(buf, count);
836
837 if (number < 0) {
838 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
839 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300840 return count;
841 }
842
843 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300844 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
845 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300846
847 sdio_al_test_initial_dev_and_chan(test_ctx);
848
849 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
850
851 ret = test_start();
852
853 if (ret)
854 break;
855 }
856
857 return count;
858}
859
860static ssize_t rmnet_a2_perf_test_read(struct file *file,
861 char __user *buffer,
862 size_t count,
863 loff_t *offset)
864{
865 memset((void *)buffer, 0, count);
866
867 snprintf(buffer, count,
868 "\nRMNET_A2_PERFORMANCE_TEST\n"
869 "=========================\n"
870 "Description:\n"
871 "TBD\n");
872
873 if (message_repeat == 1) {
874 message_repeat = 0;
875 return strnlen(buffer, count);
876 } else {
877 return 0;
878 }
879}
880
881const struct file_operations rmnet_a2_perf_test_ops = {
882 .open = sdio_al_test_open,
883 .write = rmnet_a2_perf_test_write,
884 .read = rmnet_a2_perf_test_read,
885};
886
887/* DUN A2 PERFORMANCE TEST */
888static ssize_t dun_a2_perf_test_write(struct file *file,
889 const char __user *buf,
890 size_t count,
891 loff_t *ppos)
892{
893 int ret = 0;
894 int i = 0;
895 int number = -1;
896
897 pr_info(TEST_MODULE_NAME "-- DUN A2 PERFORMANCE TEST --\n");
898
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300899 number = sdio_al_test_extract_number(buf, count);
900
901 if (number < 0) {
902 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
903 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300904 return count;
905 }
906
907 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +0300908 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
909 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +0300910
911 sdio_al_test_initial_dev_and_chan(test_ctx);
912
913 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_DUN]);
914
915 ret = test_start();
916
917 if (ret)
918 break;
919 }
920
921 return count;
922}
923
924static ssize_t dun_a2_perf_test_read(struct file *file,
925 char __user *buffer,
926 size_t count,
927 loff_t *offset)
928{
929 memset((void *)buffer, 0, count);
930
931 snprintf(buffer, count,
932 "\nDUN_A2_PERFORMANCE_TEST\n"
933 "=======================\n"
934 "Description:\n"
935 "TBD\n");
936
937 if (message_repeat == 1) {
938 message_repeat = 0;
939 return strnlen(buffer, count);
940 } else {
941 return 0;
942 }
943}
944
945const struct file_operations dun_a2_perf_test_ops = {
946 .open = sdio_al_test_open,
947 .write = dun_a2_perf_test_write,
948 .read = dun_a2_perf_test_read,
949};
950
Maya Erez241eb922011-10-23 10:51:26 +0200951/* CSVT A2 PERFORMANCE TEST */
952static ssize_t csvt_a2_perf_test_write(struct file *file,
953 const char __user *buf,
954 size_t count,
955 loff_t *ppos)
956{
957 int ret = 0;
958 int i = 0;
959 int number = -1;
960
961 pr_info(TEST_MODULE_NAME "-- CSVT A2 PERFORMANCE TEST --\n");
962
963 number = sdio_al_test_extract_number(buf, count);
964
965 if (number < 0) {
966 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
967 "failed. number = %d\n", __func__, number);
968 return count;
969 }
970
971 for (i = 0 ; i < number ; ++i) {
972 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
973 pr_info(TEST_MODULE_NAME " ===================");
974
975 sdio_al_test_initial_dev_and_chan(test_ctx);
976
977 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_CSVT]);
978
979 ret = test_start();
980
981 if (ret)
982 break;
983 }
984
985 return count;
986}
987
988static ssize_t csvt_a2_perf_test_read(struct file *file,
989 char __user *buffer,
990 size_t count,
991 loff_t *offset)
992{
993 memset((void *)buffer, 0, count);
994
995 snprintf(buffer, count,
996 "\nCSVT_A2_PERFORMANCE_TEST\n"
997 "========================\n"
998 "Description:\n"
999 "Loopback test on the CSVT Channel, in order to check "
1000 "throughput performance.\n"
1001 "Packet size that are sent on the CSVT channel in this "
1002 "test is %d.bytes\n\n"
1003 "END OF DESCRIPTION\n", CSVT_PACKET_SIZE);
1004
1005 if (message_repeat == 1) {
1006 message_repeat = 0;
1007 return strnlen(buffer, count);
1008 } else {
1009 return 0;
1010 }
1011}
1012
1013const struct file_operations csvt_a2_perf_test_ops = {
1014 .open = sdio_al_test_open,
1015 .write = csvt_a2_perf_test_write,
1016 .read = csvt_a2_perf_test_read,
1017};
1018
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001019/* RMNET DUN A2 PERFORMANCE TEST */
1020static ssize_t rmnet_dun_a2_perf_test_write(struct file *file,
1021 const char __user *buf,
1022 size_t count,
1023 loff_t *ppos)
1024{
1025 int ret = 0;
1026 int i = 0;
1027 int number = -1;
1028
1029 pr_info(TEST_MODULE_NAME "-- RMNET AND DUN A2 PERFORMANCE TEST --\n");
1030
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001031 number = sdio_al_test_extract_number(buf, count);
1032
1033 if (number < 0) {
1034 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1035 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001036 return count;
1037 }
1038
1039 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001040 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1041 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001042
1043 sdio_al_test_initial_dev_and_chan(test_ctx);
1044
1045 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
1046 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_DUN]);
1047
1048 ret = test_start();
1049
1050 if (ret)
1051 break;
1052 }
1053
1054 return count;
1055}
1056
1057static ssize_t rmnet_dun_a2_perf_test_read(struct file *file,
1058 char __user *buffer,
1059 size_t count,
1060 loff_t *offset)
1061{
1062 memset((void *)buffer, 0, count);
1063
1064 snprintf(buffer, count,
1065 "\nRMNET_DUN_A2_PERFORMANCE_TEST\n"
1066 "=============================\n"
1067 "Description:\n"
1068 "TBD\n");
1069
1070 if (message_repeat == 1) {
1071 message_repeat = 0;
1072 return strnlen(buffer, count);
1073 } else {
1074 return 0;
1075 }
1076}
1077
1078const struct file_operations rmnet_dun_a2_perf_test_ops = {
1079 .open = sdio_al_test_open,
1080 .write = rmnet_dun_a2_perf_test_write,
1081 .read = rmnet_dun_a2_perf_test_read,
1082};
1083
1084/* RPC SENDER & RMNET A2 PERFORMANCE TEST */
1085static ssize_t rpc_sender_rmnet_a2_perf_test_write(struct file *file,
1086 const char __user *buf,
1087 size_t count,
1088 loff_t *ppos)
1089{
1090 int ret = 0;
1091 int i = 0;
1092 int number = -1;
1093
1094 pr_info(TEST_MODULE_NAME "--RPC SENDER AND RMNET A2 "
1095 "PERFORMANCE --\n");
1096
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001097 number = sdio_al_test_extract_number(buf, count);
1098
1099 if (number < 0) {
1100 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1101 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001102 return count;
1103 }
1104
1105 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001106 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1107 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001108
1109 sdio_al_test_initial_dev_and_chan(test_ctx);
1110
1111 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
1112 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
1113
1114 ret = test_start();
1115
1116 if (ret)
1117 break;
1118 }
1119
1120 return count;
1121}
1122
1123static ssize_t rpc_sender_rmnet_a2_perf_test_read(struct file *file,
1124 char __user *buffer,
1125 size_t count,
1126 loff_t *offset)
1127{
1128 memset((void *)buffer, 0, count);
1129
1130 snprintf(buffer, count,
1131 "\nRPC_SENDER_RMNET_A2_PERFORMANCE_TEST\n"
1132 "====================================\n"
1133 "Description:\n"
1134 "TBD\n");
1135
1136 if (message_repeat == 1) {
1137 message_repeat = 0;
1138 return strnlen(buffer, count);
1139 } else {
1140 return 0;
1141 }
1142}
1143
1144const struct file_operations rpc_sender_rmnet_a2_perf_test_ops = {
1145 .open = sdio_al_test_open,
1146 .write = rpc_sender_rmnet_a2_perf_test_write,
1147 .read = rpc_sender_rmnet_a2_perf_test_read,
1148};
1149
1150/* ALL CHANNELS TEST */
1151static ssize_t all_channels_test_write(struct file *file,
1152 const char __user *buf,
1153 size_t count,
1154 loff_t *ppos)
1155{
1156 int ret = 0;
1157 int i = 0;
1158 int number = -1;
1159
1160 pr_info(TEST_MODULE_NAME "-- ALL THE CHANNELS TEST --\n");
1161
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001162 number = sdio_al_test_extract_number(buf, count);
1163
1164 if (number < 0) {
1165 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1166 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001167 return count;
1168 }
1169
1170 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001171 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1172 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001173
1174 sdio_al_test_initial_dev_and_chan(test_ctx);
1175
1176 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
1177 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_QMI]);
1178 set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_DIAG]);
1179 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
1180 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_DUN]);
1181 set_params_smem_test(test_ctx->test_ch_arr[SDIO_SMEM]);
Maya Erez241eb922011-10-23 10:51:26 +02001182 set_params_a2_perf(test_ctx->test_ch_arr[SDIO_CSVT]);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001183
1184 ret = test_start();
1185
1186 if (ret)
1187 break;
1188 }
1189
1190 return count;
1191}
1192
1193static ssize_t all_channels_test_read(struct file *file,
1194 char __user *buffer,
1195 size_t count,
1196 loff_t *offset)
1197{
1198 memset((void *)buffer, 0, count);
1199
1200 snprintf(buffer, count,
1201 "\nALL_CHANNELS_TEST\n"
1202 "=================\n"
1203 "Description:\n"
1204 "TBD\n");
1205
1206 if (message_repeat == 1) {
1207 message_repeat = 0;
1208 return strnlen(buffer, count);
1209 } else {
1210 return 0;
1211 }
1212}
1213
1214const struct file_operations all_channels_test_ops = {
1215 .open = sdio_al_test_open,
1216 .write = all_channels_test_write,
1217 .read = all_channels_test_read,
1218};
1219
1220/* HOST SENDER NO LP DIAG TEST */
1221static ssize_t host_sender_no_lp_diag_test_write(struct file *file,
1222 const char __user *buf,
1223 size_t count,
1224 loff_t *ppos)
1225{
1226 int ret = 0;
1227 int i = 0;
1228 int number = -1;
1229
1230 pr_info(TEST_MODULE_NAME "-- HOST SENDER NO LP FOR DIAG TEST --");
1231
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001232 number = sdio_al_test_extract_number(buf, count);
1233
1234 if (number < 0) {
1235 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1236 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001237 return count;
1238 }
1239
1240 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001241 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1242 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001243
1244 sdio_al_test_initial_dev_and_chan(test_ctx);
1245
1246 set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_DIAG]);
1247
1248 ret = test_start();
1249
1250 if (ret)
1251 break;
1252 }
1253
1254 return count;
1255}
1256
1257static ssize_t host_sender_no_lp_diag_test_read(struct file *file,
1258 char __user *buffer,
1259 size_t count,
1260 loff_t *offset)
1261{
1262 memset((void *)buffer, 0, count);
1263
1264 snprintf(buffer, count,
1265 "\nHOST_SENDER_NO_LP_DIAG_TEST\n"
1266 "===========================\n"
1267 "Description:\n"
1268 "TBD\n");
1269
1270 if (message_repeat == 1) {
1271 message_repeat = 0;
1272 return strnlen(buffer, count);
1273 } else {
1274 return 0;
1275 }
1276}
1277
1278const struct file_operations host_sender_no_lp_diag_test_ops = {
1279 .open = sdio_al_test_open,
1280 .write = host_sender_no_lp_diag_test_write,
1281 .read = host_sender_no_lp_diag_test_read,
1282};
1283
Venkat Gopalakrishnanc4093f92012-01-13 17:57:31 -08001284/* HOST SENDER NO LP DIAG, RPC TEST */
1285static ssize_t host_sender_no_lp_diag_rpc_test_write(
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001286 struct file *file,
1287 const char __user *buf,
1288 size_t count,
1289 loff_t *ppos)
1290{
1291 int ret = 0;
1292 int i = 0;
1293 int number = -1;
1294
Venkat Gopalakrishnanc4093f92012-01-13 17:57:31 -08001295 pr_info(TEST_MODULE_NAME "-- HOST SENDER NO LP FOR DIAG, RPC "
1296 "TEST --");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001297
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001298 number = sdio_al_test_extract_number(buf, count);
1299
1300 if (number < 0) {
1301 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1302 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001303 return count;
1304 }
1305
1306 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001307 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1308 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001309
1310 sdio_al_test_initial_dev_and_chan(test_ctx);
1311
1312 set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_DIAG]);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001313 set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_RPC]);
1314
1315 ret = test_start();
1316
1317 if (ret)
1318 break;
1319 }
1320
1321 return count;
1322}
1323
Venkat Gopalakrishnanc4093f92012-01-13 17:57:31 -08001324static ssize_t host_sender_no_lp_diag_rpc_test_read(
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001325 struct file *file,
1326 char __user *buffer,
1327 size_t count,
1328 loff_t *offset)
1329{
1330 memset((void *)buffer, 0, count);
1331
1332 snprintf(buffer, count,
Venkat Gopalakrishnanc4093f92012-01-13 17:57:31 -08001333 "\nHOST_SENDER_NO_LP_DIAG_RPC_TEST\n"
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001334 "===================================\n"
1335 "Description:\n"
1336 "TBD\n");
1337
1338 if (message_repeat == 1) {
1339 message_repeat = 0;
1340 return strnlen(buffer, count);
1341 } else {
1342 return 0;
1343 }
1344}
1345
Venkat Gopalakrishnanc4093f92012-01-13 17:57:31 -08001346const struct file_operations host_sender_no_lp_diag_rpc_test_ops = {
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001347 .open = sdio_al_test_open,
Venkat Gopalakrishnanc4093f92012-01-13 17:57:31 -08001348 .write = host_sender_no_lp_diag_rpc_test_write,
1349 .read = host_sender_no_lp_diag_rpc_test_read,
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001350};
1351
1352/* RMNET SMALL PACKETS TEST */
1353static ssize_t rmnet_small_packets_test_write(struct file *file,
1354 const char __user *buf,
1355 size_t count,
1356 loff_t *ppos)
1357{
1358 int ret = 0;
1359 int i = 0;
1360 int number = -1;
1361
1362 pr_info(TEST_MODULE_NAME "-- RMNET SMALL PACKETS (5-128) TEST --");
1363
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001364 number = sdio_al_test_extract_number(buf, count);
1365
1366 if (number < 0) {
1367 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1368 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001369 return count;
1370 }
1371
1372 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001373 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1374 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001375
1376 sdio_al_test_initial_dev_and_chan(test_ctx);
1377
1378 set_params_a2_small_pkts(test_ctx->test_ch_arr[SDIO_RMNT]);
1379
1380 ret = test_start();
1381
1382 if (ret)
1383 break;
1384 }
1385
1386 return count;
1387}
1388
1389static ssize_t rmnet_small_packets_test_read(struct file *file,
1390 char __user *buffer,
1391 size_t count,
1392 loff_t *offset)
1393{
1394 memset((void *)buffer, 0, count);
1395
1396 snprintf(buffer, count,
1397 "\nRMNET_SMALL_PACKETS_TEST\n"
1398 "========================\n"
1399 "Description:\n"
1400 "TBD\n");
1401
1402 if (message_repeat == 1) {
1403 message_repeat = 0;
1404 return strnlen(buffer, count);
1405 } else {
1406 return 0;
1407 }
1408}
1409
1410const struct file_operations rmnet_small_packets_test_ops = {
1411 .open = sdio_al_test_open,
1412 .write = rmnet_small_packets_test_write,
1413 .read = rmnet_small_packets_test_read,
1414};
1415
1416/* RMNET RTT TEST */
1417static ssize_t rmnet_rtt_test_write(struct file *file,
1418 const char __user *buf,
1419 size_t count,
1420 loff_t *ppos)
1421{
1422 int ret = 0;
1423 int i = 0;
1424 int number = -1;
1425
1426 pr_info(TEST_MODULE_NAME "-- RMNET RTT TEST --");
1427
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001428 number = sdio_al_test_extract_number(buf, count);
1429
1430 if (number < 0) {
1431 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1432 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001433 return count;
1434 }
1435
1436 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001437 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1438 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001439
1440 sdio_al_test_initial_dev_and_chan(test_ctx);
1441
1442 set_params_rtt(test_ctx->test_ch_arr[SDIO_RMNT]);
1443
1444 ret = test_start();
1445
1446 if (ret)
1447 break;
1448 }
1449
1450 return count;
1451}
1452
1453static ssize_t rmnet_rtt_test_read(struct file *file,
1454 char __user *buffer,
1455 size_t count,
1456 loff_t *offset)
1457{
1458 memset((void *)buffer, 0, count);
1459
1460 snprintf(buffer, count,
1461 "\nRMNET_RTT_TEST\n"
1462 "==============\n"
1463 "Description:\n"
1464 "TBD\n");
1465
1466 if (message_repeat == 1) {
1467 message_repeat = 0;
1468 return strnlen(buffer, count);
1469 } else {
1470 return 0;
1471 }
1472}
1473
1474const struct file_operations rmnet_rtt_test_ops = {
1475 .open = sdio_al_test_open,
1476 .write = rmnet_rtt_test_write,
1477 .read = rmnet_rtt_test_read,
1478};
1479
Maya Erez241eb922011-10-23 10:51:26 +02001480/* CSVT RTT TEST */
1481static ssize_t csvt_rtt_test_write(struct file *file,
1482 const char __user *buf,
1483 size_t count,
1484 loff_t *ppos)
1485{
1486 int ret = 0;
1487 int i = 0;
1488 int number = -1;
1489
1490 pr_info(TEST_MODULE_NAME "-- CSVT RTT TEST --");
1491
1492 number = sdio_al_test_extract_number(buf, count);
1493
1494 if (number < 0) {
1495 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1496 "failed. number = %d\n", __func__, number);
1497 return count;
1498 }
1499
1500 for (i = 0 ; i < number ; ++i) {
1501 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1502 pr_info(TEST_MODULE_NAME " ===================");
1503
1504 sdio_al_test_initial_dev_and_chan(test_ctx);
1505
1506 set_params_rtt(test_ctx->test_ch_arr[SDIO_CSVT]);
1507
1508 ret = test_start();
1509
1510 if (ret)
1511 break;
1512 }
1513
1514 return count;
1515}
1516
1517static ssize_t csvt_rtt_test_read(struct file *file,
1518 char __user *buffer,
1519 size_t count,
1520 loff_t *offset)
1521{
1522 memset((void *)buffer, 0, count);
1523
1524 snprintf(buffer, count,
1525 "\nCSVT_RTT_TEST\n"
1526 "==============\n"
1527 "Description:\n"
1528 "In this test the HOST send a message of %d bytes "
1529 "to the CLIENT\n\n"
1530 "END OF DESCRIPTION\n", SDIO_CSVT_RTT_PACKET_SIZE);
1531
1532 if (message_repeat == 1) {
1533 message_repeat = 0;
1534 return strnlen(buffer, count);
1535 } else {
1536 return 0;
1537 }
1538}
1539
1540const struct file_operations csvt_rtt_test_ops = {
1541 .open = sdio_al_test_open,
1542 .write = csvt_rtt_test_write,
1543 .read = csvt_rtt_test_read,
1544};
1545
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001546/* MODEM RESET RPC TEST */
1547static ssize_t modem_reset_rpc_test_write(struct file *file,
1548 const char __user *buf,
1549 size_t count,
1550 loff_t *ppos)
1551{
1552 int ret = 0;
1553 int i = 0;
1554 int number = -1;
1555
1556 pr_info(TEST_MODULE_NAME "-- MODEM RESET - RPC CHANNEL TEST --");
1557
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001558 number = sdio_al_test_extract_number(buf, count);
1559
1560 if (number < 0) {
1561 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1562 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001563 return count;
1564 }
1565
1566 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001567 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1568 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001569
1570 sdio_al_test_initial_dev_and_chan(test_ctx);
1571
1572 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RPC]);
1573
1574 ret = test_start();
1575
1576 if (ret)
1577 break;
1578 }
1579
1580 return count;
1581}
1582
1583static ssize_t modem_reset_rpc_test_read(struct file *file,
1584 char __user *buffer,
1585 size_t count,
1586 loff_t *offset)
1587{
1588 memset((void *)buffer, 0, count);
1589
1590 snprintf(buffer, count,
1591 "\nMODEM_RESET_RPC_TEST\n"
1592 "====================\n"
1593 "Description:\n"
1594 "TBD\n");
1595
1596 if (message_repeat == 1) {
1597 message_repeat = 0;
1598 return strnlen(buffer, count);
1599 } else {
1600 return 0;
1601 }
1602}
1603
1604const struct file_operations modem_reset_rpc_test_ops = {
1605 .open = sdio_al_test_open,
1606 .write = modem_reset_rpc_test_write,
1607 .read = modem_reset_rpc_test_read,
1608};
1609
1610/* MODEM RESET RMNET TEST */
1611static ssize_t modem_reset_rmnet_test_write(struct file *file,
1612 const char __user *buf,
1613 size_t count,
1614 loff_t *ppos)
1615{
1616 int ret = 0;
1617 int i = 0;
1618 int number = -1;
1619
1620 pr_info(TEST_MODULE_NAME "-- MODEM RESET - RMNT CHANNEL TEST --");
1621
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001622 number = sdio_al_test_extract_number(buf, count);
1623
1624 if (number < 0) {
1625 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1626 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001627 return count;
1628 }
1629
1630 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001631 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1632 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001633
1634 sdio_al_test_initial_dev_and_chan(test_ctx);
1635
1636 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]);
1637
1638 ret = test_start();
1639
1640 if (ret)
1641 break;
1642 }
1643
1644 return count;
1645}
1646
1647static ssize_t modem_reset_rmnet_test_read(struct file *file,
1648 char __user *buffer,
1649 size_t count,
1650 loff_t *offset)
1651{
1652 memset((void *)buffer, 0, count);
1653
1654 snprintf(buffer, count,
1655 "\nMODEM_RESET_RMNET_TEST\n"
1656 "======================\n"
1657 "Description:\n"
1658 "TBD\n");
1659
1660 if (message_repeat == 1) {
1661 message_repeat = 0;
1662 return strnlen(buffer, count);
1663 } else {
1664 return 0;
1665 }
1666}
1667
1668const struct file_operations modem_reset_rmnet_test_ops = {
1669 .open = sdio_al_test_open,
1670 .write = modem_reset_rmnet_test_write,
1671 .read = modem_reset_rmnet_test_read,
1672};
1673
1674/* MODEM RESET - CHANNELS IN 4BIT DEVICE TEST */
1675static ssize_t modem_reset_channels_4bit_dev_test_write(
1676 struct file *file,
1677 const char __user *buf,
1678 size_t count,
1679 loff_t *ppos)
1680{
1681 int ret = 0;
1682 int i = 0;
1683 int number = -1;
1684
1685 pr_info(TEST_MODULE_NAME "-- MODEM RESET - ALL CHANNELS IN "
1686 "4BIT DEVICE TEST --");
1687
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001688 number = sdio_al_test_extract_number(buf, count);
1689
1690 if (number < 0) {
1691 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1692 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001693 return count;
1694 }
1695
1696 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001697 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1698 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001699
1700 sdio_al_test_initial_dev_and_chan(test_ctx);
1701
1702 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RPC]);
1703 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_QMI]);
1704 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DIAG]);
1705
1706 ret = test_start();
1707
1708 if (ret)
1709 break;
1710 }
1711
1712 return count;
1713}
1714
1715static ssize_t modem_reset_channels_4bit_dev_test_read(
1716 struct file *file,
1717 char __user *buffer,
1718 size_t count,
1719 loff_t *offset)
1720{
1721 memset((void *)buffer, 0, count);
1722
1723 snprintf(buffer, count,
1724 "\nMODEM_RESET_CHANNELS_4BIT_DEV_TEST\n"
1725 "==================================\n"
1726 "Description:\n"
1727 "TBD\n");
1728
1729 if (message_repeat == 1) {
1730 message_repeat = 0;
1731 return strnlen(buffer, count);
1732 } else {
1733 return 0;
1734 }
1735}
1736
1737const struct file_operations modem_reset_channels_4bit_dev_test_ops = {
1738 .open = sdio_al_test_open,
1739 .write = modem_reset_channels_4bit_dev_test_write,
1740 .read = modem_reset_channels_4bit_dev_test_read,
1741};
1742
1743/* MODEM RESET - CHANNELS IN 8BIT DEVICE TEST */
1744static ssize_t modem_reset_channels_8bit_dev_test_write(
1745 struct file *file,
1746 const char __user *buf,
1747 size_t count,
1748 loff_t *ppos)
1749{
1750 int ret = 0;
1751 int i = 0;
1752 int number = -1;
1753
1754 pr_info(TEST_MODULE_NAME "-- MODEM RESET - ALL CHANNELS IN "
1755 "8BIT DEVICE TEST --");
1756
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001757 number = sdio_al_test_extract_number(buf, count);
1758
1759 if (number < 0) {
1760 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1761 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001762 return count;
1763 }
1764
1765 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001766 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1767 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001768
1769 sdio_al_test_initial_dev_and_chan(test_ctx);
1770
1771 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]);
1772 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DUN]);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001773
1774 ret = test_start();
1775
1776 if (ret)
1777 break;
1778 }
1779
1780 return count;
1781}
1782
1783static ssize_t modem_reset_channels_8bit_dev_test_read(
1784 struct file *file,
1785 char __user *buffer,
1786 size_t count,
1787 loff_t *offset)
1788{
1789 memset((void *)buffer, 0, count);
1790
1791 snprintf(buffer, count,
1792 "\nMODEM_RESET_CHANNELS_8BIT_DEV_TEST\n"
1793 "==================================\n"
1794 "Description:\n"
1795 "TBD\n");
1796
1797 if (message_repeat == 1) {
1798 message_repeat = 0;
1799 return strnlen(buffer, count);
1800 } else {
1801 return 0;
1802 }
1803}
1804
1805const struct file_operations modem_reset_channels_8bit_dev_test_ops = {
1806 .open = sdio_al_test_open,
1807 .write = modem_reset_channels_8bit_dev_test_write,
1808 .read = modem_reset_channels_8bit_dev_test_read,
1809};
1810
1811/* MODEM RESET - ALL CHANNELS TEST */
1812static ssize_t modem_reset_all_channels_test_write(struct file *file,
1813 const char __user *buf,
1814 size_t count,
1815 loff_t *ppos)
1816{
1817 int ret = 0;
1818 int i = 0;
1819 int number = -1;
1820
1821 pr_info(TEST_MODULE_NAME "-- MODEM RESET - ALL CHANNELS TEST --");
1822
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001823 number = sdio_al_test_extract_number(buf, count);
1824
1825 if (number < 0) {
1826 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1827 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001828 return count;
1829 }
1830
1831 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001832 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1833 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001834
1835 sdio_al_test_initial_dev_and_chan(test_ctx);
1836
1837 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RPC]);
1838 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_QMI]);
1839 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DIAG]);
1840 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]);
1841 set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DUN]);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001842
1843 ret = test_start();
1844
1845 if (ret)
1846 break;
1847 }
1848
1849 return count;
1850}
1851
1852static ssize_t modem_reset_all_channels_test_read(struct file *file,
1853 char __user *buffer,
1854 size_t count,
1855 loff_t *offset)
1856{
1857 memset((void *)buffer, 0, count);
1858
1859 snprintf(buffer, count,
1860 "\nMODEM_RESET_ALL_CHANNELS_TEST\n"
1861 "=============================\n"
1862 "Description:\n"
1863 "TBD\n");
1864
1865 if (message_repeat == 1) {
1866 message_repeat = 0;
1867 return strnlen(buffer, count);
1868 } else {
1869 return 0;
1870 }
1871}
1872
1873const struct file_operations modem_reset_all_channels_test_ops = {
1874 .open = sdio_al_test_open,
1875 .write = modem_reset_all_channels_test_write,
1876 .read = modem_reset_all_channels_test_read,
1877};
1878
Maya Erezefafaa82011-09-21 12:41:28 +03001879/* HOST SENDER WITH OPEN/CLOSE TEST */
1880static ssize_t open_close_test_write(struct file *file,
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001881 const char __user *buf,
1882 size_t count,
1883 loff_t *ppos)
1884{
1885 int ret = 0;
1886 struct test_channel **ch_arr = test_ctx->test_ch_arr;
1887 int i = 0;
1888 int number = -1;
1889
Maya Erezefafaa82011-09-21 12:41:28 +03001890 pr_info(TEST_MODULE_NAME "-- HOST SENDER WITH OPEN/CLOSE TEST --");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001891
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001892 number = sdio_al_test_extract_number(buf, count);
1893
1894 if (number < 0) {
1895 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1896 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001897 return count;
1898 }
1899
1900 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03001901 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1902 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001903
1904 sdio_al_test_initial_dev_and_chan(test_ctx);
1905
1906 set_params_loopback_9k_close(ch_arr[SDIO_DIAG]);
Maya Erezefafaa82011-09-21 12:41:28 +03001907 set_params_loopback_9k_close(ch_arr[SDIO_RPC]);
1908 set_params_loopback_9k_close(ch_arr[SDIO_SMEM]);
1909 set_params_loopback_9k_close(ch_arr[SDIO_QMI]);
Maya Ereze05fc4d2011-09-11 14:18:43 +03001910 set_params_loopback_9k_close(ch_arr[SDIO_RMNT]);
Maya Erezefafaa82011-09-21 12:41:28 +03001911 set_params_loopback_9k_close(ch_arr[SDIO_DUN]);
Maya Erez241eb922011-10-23 10:51:26 +02001912 set_params_loopback_9k_close(ch_arr[SDIO_CSVT]);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001913
1914 ret = test_start();
1915
1916 if (ret)
1917 break;
1918
1919 pr_info(TEST_MODULE_NAME " -- correctness test for"
Venkat Gopalakrishnanc4093f92012-01-13 17:57:31 -08001920 "DIAG ");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001921 set_params_loopback_9k(ch_arr[SDIO_DIAG]);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001922
1923 ret = test_start();
1924
1925 if (ret)
1926 break;
1927 }
1928
1929 return count;
1930}
1931
Maya Erezefafaa82011-09-21 12:41:28 +03001932static ssize_t open_close_test_read(struct file *file,
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001933 char __user *buffer,
1934 size_t count,
1935 loff_t *offset)
1936{
1937 memset((void *)buffer, 0, count);
1938
1939 snprintf(buffer, count,
Maya Erezefafaa82011-09-21 12:41:28 +03001940 "\nOPEN_CLOSE_TEST\n"
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001941 "============================\n"
1942 "Description:\n"
Maya Ereze05fc4d2011-09-11 14:18:43 +03001943 "In this test the host sends 5k packets to the modem in the "
1944 "following sequence: Send a random burst of packets on "
Venkat Gopalakrishnanc4093f92012-01-13 17:57:31 -08001945 "Diag and Rmnet channels, read 0 or a random number "
Maya Ereze05fc4d2011-09-11 14:18:43 +03001946 "of packets, close and re-open the channel. At the end of the "
Maya Erez241eb922011-10-23 10:51:26 +02001947 "test, the channel is verified by running a loopback test\n\n"
1948 "END OF DESCRIPTION\n");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001949
1950 if (message_repeat == 1) {
1951 message_repeat = 0;
1952 return strnlen(buffer, count);
1953 } else {
1954 return 0;
1955 }
1956}
1957
Maya Erezefafaa82011-09-21 12:41:28 +03001958const struct file_operations open_close_test_ops = {
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03001959 .open = sdio_al_test_open,
Maya Erezefafaa82011-09-21 12:41:28 +03001960 .write = open_close_test_write,
1961 .read = open_close_test_read,
Maya Ereze05fc4d2011-09-11 14:18:43 +03001962};
1963
Maya Ereze05fc4d2011-09-11 14:18:43 +03001964/* HOST SENDER WITH OPEN/CLOSE FOR DUN & RMNET TEST */
1965static ssize_t open_close_dun_rmnet_test_write(struct file *file,
1966 const char __user *buf,
1967 size_t count,
1968 loff_t *ppos)
1969{
1970 int ret = 0;
1971 struct test_channel **ch_arr = test_ctx->test_ch_arr;
1972 int i = 0;
1973 int number = -1;
1974
1975 pr_info(TEST_MODULE_NAME "-- HOST SENDER WITH OPEN/CLOSE FOR "
1976 "DUN AND RMNET TEST --");
1977
1978 number = sdio_al_test_extract_number(buf, count);
1979
1980 if (number < 0) {
1981 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
1982 "failed. number = %d\n", __func__, number);
1983 return count;
1984 }
1985
1986 for (i = 0 ; i < number ; ++i) {
1987 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
1988 pr_info(TEST_MODULE_NAME " ===================");
1989
1990 sdio_al_test_initial_dev_and_chan(test_ctx);
1991
1992 set_params_loopback_9k_close(ch_arr[SDIO_DUN]);
1993 set_params_loopback_9k_close(ch_arr[SDIO_RMNT]);
1994
1995 ret = test_start();
1996
1997 if (ret)
1998 break;
1999 }
2000
2001 return count;
2002}
2003
2004static ssize_t open_close_dun_rmnet_test_read(struct file *file,
2005 char __user *buffer,
2006 size_t count,
2007 loff_t *offset)
2008{
2009 memset((void *)buffer, 0, count);
2010
2011 snprintf(buffer, count,
2012 "\nOPEN_CLOSE_DUN_RMNET_TEST\n"
2013 "============================\n"
2014 "Description:\n"
2015 "In this test the host sends 5k packets to the modem in the "
2016 "following sequence: Send a random burst of packets on "
2017 "DUN and Rmnet channels, read 0 or a random number "
Maya Erez241eb922011-10-23 10:51:26 +02002018 "of packets, close and re-open the channel.\n\n"
2019 "END OF DESCRIPTION\n");
Maya Ereze05fc4d2011-09-11 14:18:43 +03002020
2021 if (message_repeat == 1) {
2022 message_repeat = 0;
2023 return strnlen(buffer, count);
2024 } else {
2025 return 0;
2026 }
2027}
2028
2029const struct file_operations open_close_dun_rmnet_test_ops = {
2030 .open = sdio_al_test_open,
2031 .write = open_close_dun_rmnet_test_write,
2032 .read = open_close_dun_rmnet_test_read,
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002033};
2034
2035/* CLOSE CHANNEL & LPM TEST HOST WAKES THE CLIENT TEST */
2036static ssize_t close_chan_lpm_test_write(struct file *file,
2037 const char __user *buf,
2038 size_t count,
2039 loff_t *ppos)
2040{
2041 int ret = 0;
2042 int i = 0;
Yaniv Gardib4237782011-08-31 20:06:16 +03002043 int channel_num = 0;
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002044 int number = -1;
2045
2046 pr_info(TEST_MODULE_NAME "-- CLOSE CHANNEL & LPM TEST "
2047 "HOST WAKES THE CLIENT TEST --\n");
2048
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03002049 number = sdio_al_test_extract_number(buf, count);
2050
2051 if (number < 0) {
2052 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
2053 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002054 return count;
2055 }
2056
2057 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03002058 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
2059 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002060
2061 sdio_al_test_initial_dev_and_chan(test_ctx);
2062
Yaniv Gardib4237782011-08-31 20:06:16 +03002063 for (channel_num = 0 ; channel_num < SDIO_MAX_CHANNELS ;
2064 channel_num++) {
Yaniv Gardib4237782011-08-31 20:06:16 +03002065
2066 ret = close_channel_lpm_test(channel_num);
2067
2068 if (ret)
2069 break;
2070
2071 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
2072 SDIO_TEST_LPM_HOST_WAKER, 120);
2073
2074 ret = test_start();
2075
2076 if (ret)
2077 break;
2078 }
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002079
2080 if (ret) {
2081 pr_err(TEST_MODULE_NAME " -- Close channel & LPM Test "
2082 "FAILED: %d --\n", ret);
2083 } else {
2084 pr_err(TEST_MODULE_NAME " -- Close channel & LPM Test "
2085 "PASSED\n");
2086 }
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002087 }
2088
2089 return count;
2090}
2091
2092static ssize_t close_chan_lpm_test_read(struct file *file,
2093 char __user *buffer,
2094 size_t count,
2095 loff_t *offset)
2096{
2097 memset((void *)buffer, 0, count);
2098
2099 snprintf(buffer, count,
2100 "\nCLOSE_CHAN_LPM_TEST\n"
2101 "===================\n"
2102 "Description:\n"
2103 "TBD\n");
2104
2105 if (message_repeat == 1) {
2106 message_repeat = 0;
2107 return strnlen(buffer, count);
2108 } else {
2109 return 0;
2110 }
2111}
2112
2113const struct file_operations close_chan_lpm_test_ops = {
2114 .open = sdio_al_test_open,
2115 .write = close_chan_lpm_test_write,
2116 .read = close_chan_lpm_test_read,
2117};
2118
2119/* LPM TEST FOR DEVICE 1. CLIENT WAKES THE HOST TEST */
2120static ssize_t lpm_test_client_wakes_host_test_write(struct file *file,
2121 const char __user *buf,
2122 size_t count,
2123 loff_t *ppos)
2124{
2125 int ret = 0;
2126 int i = 0;
2127 int number = -1;
2128
2129 pr_info(TEST_MODULE_NAME "-- LPM TEST FOR DEVICE 1. CLIENT "
2130 "WAKES THE HOST TEST --\n");
2131
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03002132 number = sdio_al_test_extract_number(buf, count);
2133
2134 if (number < 0) {
2135 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
2136 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002137 return count;
2138 }
2139
2140 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03002141 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
2142 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002143
2144 sdio_al_test_initial_dev_and_chan(test_ctx);
2145
2146 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
2147 SDIO_TEST_LPM_CLIENT_WAKER, 90);
2148
2149 ret = test_start();
2150
2151 if (ret)
2152 break;
2153 }
2154
2155 return count;
2156}
2157
2158static ssize_t lpm_test_client_wakes_host_test_read(struct file *file,
2159 char __user *buffer,
2160 size_t count,
2161 loff_t *offset)
2162{
2163 memset((void *)buffer, 0, count);
2164
2165 snprintf(buffer, count,
2166 "\nLPM_TEST_CLIENT_WAKES_HOST_TEST\n"
2167 "===============================\n"
2168 "Description:\n"
2169 "In this test, the HOST is going into LPM mode,\n"
2170 "and the CLIENT is responsible to send it a message\n"
2171 "in order to wake it up\n\n"
2172 "END OF DESCRIPTION\n");
2173
2174 if (message_repeat == 1) {
2175 message_repeat = 0;
2176 return strnlen(buffer, count);
2177 } else {
2178 return 0;
2179 }
2180}
2181
2182const struct file_operations lpm_test_client_wakes_host_test_ops = {
2183 .open = sdio_al_test_open,
2184 .write = lpm_test_client_wakes_host_test_write,
2185 .read = lpm_test_client_wakes_host_test_read,
2186};
2187
2188/* LPM TEST FOR DEVICE 1. HOST WAKES THE CLIENT TEST */
2189static ssize_t lpm_test_host_wakes_client_test_write(struct file *file,
2190 const char __user *buf,
2191 size_t count,
2192 loff_t *ppos)
2193{
2194 int ret = 0;
2195 int i = 0;
2196 int number = -1;
2197
2198 pr_info(TEST_MODULE_NAME "-- LPM TEST FOR DEVICE 1. HOST "
2199 "WAKES THE CLIENT TEST --\n");
2200
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03002201 number = sdio_al_test_extract_number(buf, count);
2202
2203 if (number < 0) {
2204 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
2205 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002206 return count;
2207 }
2208
2209 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03002210 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
2211 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002212
2213 sdio_al_test_initial_dev_and_chan(test_ctx);
2214
2215 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
2216 SDIO_TEST_LPM_HOST_WAKER, 120);
2217
2218 ret = test_start();
2219
2220 if (ret)
2221 break;
2222 }
2223
2224 return count;
2225}
2226
2227static ssize_t lpm_test_host_wakes_client_test_read(struct file *file,
2228 char __user *buffer,
2229 size_t count,
2230 loff_t *offset)
2231{
2232 memset((void *)buffer, 0, count);
2233
2234 snprintf(buffer, count,
2235 "\nLPM_TEST_HOST_WAKES_CLIENT_TEST\n"
2236 "===============================\n"
2237 "Description:\n"
2238 "In this test, the CLIENT goes into LPM mode, and the\n"
2239 "HOST is responsible to send it a message\n"
2240 "in order to wake it up\n\n"
2241 "END OF DESCRIPTION\n");
2242
2243 if (message_repeat == 1) {
2244 message_repeat = 0;
2245 return strnlen(buffer, count);
2246 } else {
2247 return 0;
2248 }
2249}
2250
2251const struct file_operations lpm_test_host_wakes_client_test_ops = {
2252 .open = sdio_al_test_open,
2253 .write = lpm_test_host_wakes_client_test_write,
2254 .read = lpm_test_host_wakes_client_test_read,
2255};
2256
2257/* LPM TEST RANDOM, SINGLE CHANNEL TEST */
2258static ssize_t lpm_test_random_single_channel_test_write(
2259 struct file *file,
2260 const char __user *buf,
2261 size_t count,
2262 loff_t *ppos)
2263{
2264 int ret = 0;
2265 int i = 0;
2266 int number = -1;
2267
2268 pr_info(TEST_MODULE_NAME "-- LPM TEST RANDOM SINGLE "
2269 "CHANNEL TEST --\n");
2270
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03002271 number = sdio_al_test_extract_number(buf, count);
2272
2273 if (number < 0) {
2274 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
2275 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002276 return count;
2277 }
2278
2279 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03002280 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
2281 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002282
2283 sdio_al_test_initial_dev_and_chan(test_ctx);
2284
2285 set_pseudo_random_seed();
2286 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
2287 SDIO_TEST_LPM_RANDOM, 0);
2288
2289 ret = test_start();
2290
2291 if (ret)
2292 break;
2293 }
2294
2295 return count;
2296}
2297
2298static ssize_t lpm_test_random_single_channel_test_read(
2299 struct file *file,
2300 char __user *buffer,
2301 size_t count,
2302 loff_t *offset)
2303{
2304 memset((void *)buffer, 0, count);
2305
2306 snprintf(buffer, count,
2307 "\nLPM_TEST_RANDOM_SINGLE_CHANNEL_TEST\n"
2308 "===================================\n"
2309 "Description:\n"
2310 "In this test, the HOST and CLIENT "
2311 "send messages to each other,\n"
2312 "random in time, over RPC channel only.\n"
2313 "All events are being recorded, and later on,\n"
2314 "they are being analysed by the HOST and by the CLIENT\n,"
2315 "in order to check if the LPM mechanism worked properly,\n"
2316 "meaning:"
2317 " When all the relevant conditions are met, a device should:\n"
2318 "1. Go to sleep\n"
2319 "2. Wake up\n"
2320 "3. Stay awake\n\n"
2321 "END OF DESCRIPTION\n");
2322
2323 if (message_repeat == 1) {
2324 message_repeat = 0;
2325 return strnlen(buffer, count);
2326 } else {
2327 return 0;
2328 }
2329}
2330
2331const struct file_operations lpm_test_random_single_channel_test_ops = {
2332 .open = sdio_al_test_open,
2333 .write = lpm_test_random_single_channel_test_write,
2334 .read = lpm_test_random_single_channel_test_read,
2335};
2336
2337/* LPM TEST RANDOM, MULTI CHANNEL TEST */
2338static ssize_t lpm_test_random_multi_channel_test_write(
2339 struct file *file,
2340 const char __user *buf,
2341 size_t count,
2342 loff_t *ppos)
2343{
2344 int ret = 0;
2345 int i = 0;
2346 int number = -1;
2347
2348 pr_info(TEST_MODULE_NAME "-- LPM TEST RANDOM MULTI CHANNEL TEST --\n");
2349
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03002350 number = sdio_al_test_extract_number(buf, count);
2351
2352 if (number < 0) {
2353 pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
2354 "failed. number = %d\n", __func__, number);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002355 return count;
2356 }
2357
2358 for (i = 0 ; i < number ; ++i) {
Yaniv Gardifa8b71e2011-09-06 14:00:55 +03002359 pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
2360 pr_info(TEST_MODULE_NAME " ===================");
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002361
2362 sdio_al_test_initial_dev_and_chan(test_ctx);
2363
2364 set_pseudo_random_seed();
2365
2366 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
2367 SDIO_TEST_LPM_RANDOM, 0);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002368 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_DIAG],
2369 SDIO_TEST_LPM_RANDOM, 0);
2370 set_params_lpm_test(test_ctx->test_ch_arr[SDIO_QMI],
2371 SDIO_TEST_LPM_RANDOM, 0);
2372
2373 ret = test_start();
2374
2375 if (ret)
2376 break;
2377 }
2378
2379 return count;
2380}
2381
2382static ssize_t lpm_test_random_multi_channel_test_read(
2383 struct file *file,
2384 char __user *buffer,
2385 size_t count,
2386 loff_t *offset)
2387{
2388 memset((void *)buffer, 0, count);
2389
2390 snprintf(buffer, count,
2391 "\nLPM_TEST_RANDOM_MULTI_CHANNEL_TEST\n"
2392 "==================================\n"
2393 "Description:\n"
2394 "In this test, the HOST and CLIENT "
2395 "send messages to each other,\n"
Venkat Gopalakrishnanc4093f92012-01-13 17:57:31 -08002396 "random in time, over RPC, QMI AND DIAG channels\n"
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002397 "(i.e, on both SDIO devices).\n"
2398 "All events are being recorded, and later on,\n"
2399 "they are being analysed by the HOST and by the CLIENT,\n"
2400 "in order to check if the LPM mechanism worked properly,\n"
2401 "meaning:"
2402 " When all the relevant conditions are met, a device should:\n"
2403 "1. Go to sleep\n"
2404 "2. Wake up\n"
2405 "3. Stay awake\n\n"
2406 "END OF DESCRIPTION\n");
2407
2408 if (message_repeat == 1) {
2409 message_repeat = 0;
2410 return strnlen(buffer, count);
2411 } else {
2412 return 0;
2413 }
2414}
2415
2416const struct file_operations lpm_test_random_multi_channel_test_ops = {
2417 .open = sdio_al_test_open,
2418 .write = lpm_test_random_multi_channel_test_write,
2419 .read = lpm_test_random_multi_channel_test_read,
2420};
2421
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002422static int sdio_al_test_debugfs_init(void)
2423{
2424 test_ctx->debug.debug_root = debugfs_create_dir("sdio_al_test",
2425 NULL);
2426 if (!test_ctx->debug.debug_root)
2427 return -ENOENT;
2428
2429 test_ctx->debug.debug_test_result = debugfs_create_u32(
2430 "test_result",
2431 S_IRUGO | S_IWUGO,
2432 test_ctx->debug.debug_root,
2433 &test_ctx->test_result);
2434
2435 test_ctx->debug.debug_dun_throughput = debugfs_create_u32(
2436 "dun_throughput",
2437 S_IRUGO | S_IWUGO,
2438 test_ctx->debug.debug_root,
2439 &test_ctx->debug.dun_throughput);
2440
2441 test_ctx->debug.debug_rmnt_throughput = debugfs_create_u32(
2442 "rmnt_throughput",
2443 S_IRUGO | S_IWUGO,
2444 test_ctx->debug.debug_root,
2445 &test_ctx->debug.rmnt_throughput);
2446
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002447 test_ctx->debug.rpc_sender_test =
2448 debugfs_create_file("10_rpc_sender_test",
2449 S_IRUGO | S_IWUGO,
2450 test_ctx->debug.debug_root,
2451 NULL,
2452 &rpc_sender_test_ops);
2453
2454 test_ctx->debug.rpc_qmi_diag_sender_test =
2455 debugfs_create_file("20_rpc_qmi_diag_sender_test",
2456 S_IRUGO | S_IWUGO,
2457 test_ctx->debug.debug_root,
2458 NULL,
2459 &rpc_qmi_diag_sender_test_ops);
2460
Venkat Gopalakrishnandcc6aac2011-08-29 18:57:11 -07002461 test_ctx->debug.rmnet_a2_validation_test =
2462 debugfs_create_file("30_rmnet_a2_validation_test",
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002463 S_IRUGO | S_IWUGO,
2464 test_ctx->debug.debug_root,
2465 NULL,
Venkat Gopalakrishnandcc6aac2011-08-29 18:57:11 -07002466 &rmnet_a2_validation_test_ops);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002467
Venkat Gopalakrishnandcc6aac2011-08-29 18:57:11 -07002468 test_ctx->debug.dun_a2_validation_test =
2469 debugfs_create_file("40_dun_a2_validation_test",
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002470 S_IRUGO | S_IWUGO,
2471 test_ctx->debug.debug_root,
2472 NULL,
Venkat Gopalakrishnandcc6aac2011-08-29 18:57:11 -07002473 &dun_a2_validation_test_ops);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002474
2475 test_ctx->debug.rmnet_a2_perf_test =
Venkat Gopalakrishnandcc6aac2011-08-29 18:57:11 -07002476 debugfs_create_file("50_rmnet_a2_perf_test",
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002477 S_IRUGO | S_IWUGO,
2478 test_ctx->debug.debug_root,
2479 NULL,
2480 &rmnet_a2_perf_test_ops);
2481
2482 test_ctx->debug.dun_a2_perf_test =
Venkat Gopalakrishnandcc6aac2011-08-29 18:57:11 -07002483 debugfs_create_file("60_dun_a2_perf_test",
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002484 S_IRUGO | S_IWUGO,
2485 test_ctx->debug.debug_root,
2486 NULL,
2487 &dun_a2_perf_test_ops);
2488
Maya Erez241eb922011-10-23 10:51:26 +02002489 test_ctx->debug.csvt_a2_perf_test =
2490 debugfs_create_file("71_csvt_a2_perf_test",
2491 S_IRUGO | S_IWUGO,
2492 test_ctx->debug.debug_root,
2493 NULL,
2494 &csvt_a2_perf_test_ops);
2495
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002496 test_ctx->debug.rmnet_dun_a2_perf_test =
Venkat Gopalakrishnandcc6aac2011-08-29 18:57:11 -07002497 debugfs_create_file("70_rmnet_dun_a2_perf_test",
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002498 S_IRUGO | S_IWUGO,
2499 test_ctx->debug.debug_root,
2500 NULL,
2501 &rmnet_dun_a2_perf_test_ops);
2502
2503 test_ctx->debug.rpc_sender_rmnet_a2_perf_test =
Venkat Gopalakrishnandcc6aac2011-08-29 18:57:11 -07002504 debugfs_create_file("80_rpc_sender_rmnet_a2_perf_test",
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002505 S_IRUGO | S_IWUGO,
2506 test_ctx->debug.debug_root,
2507 NULL,
2508 &rpc_sender_rmnet_a2_perf_test_ops);
2509
Venkat Gopalakrishnandcc6aac2011-08-29 18:57:11 -07002510 test_ctx->debug.smem_test =
2511 debugfs_create_file("90_smem_test",
2512 S_IRUGO | S_IWUGO,
2513 test_ctx->debug.debug_root,
2514 NULL,
2515 &smem_test_ops);
2516
2517 test_ctx->debug.smem_rpc_test =
2518 debugfs_create_file("100_smem_rpc_test",
2519 S_IRUGO | S_IWUGO,
2520 test_ctx->debug.debug_root,
2521 NULL,
2522 &smem_rpc_test_ops);
2523
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002524 test_ctx->debug.all_channels_test =
Venkat Gopalakrishnandcc6aac2011-08-29 18:57:11 -07002525 debugfs_create_file("150_all_channels_test",
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002526 S_IRUGO | S_IWUGO,
2527 test_ctx->debug.debug_root,
2528 NULL,
2529 &all_channels_test_ops);
2530
2531 test_ctx->debug.host_sender_no_lp_diag_test =
2532 debugfs_create_file("160_host_sender_no_lp_diag_test",
2533 S_IRUGO | S_IWUGO,
2534 test_ctx->debug.debug_root,
2535 NULL,
2536 &host_sender_no_lp_diag_test_ops);
2537
Venkat Gopalakrishnanc4093f92012-01-13 17:57:31 -08002538 test_ctx->debug.host_sender_no_lp_diag_rpc_test =
2539 debugfs_create_file("170_host_sender_no_lp_diag_rpc_test",
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002540 S_IRUGO | S_IWUGO,
2541 test_ctx->debug.debug_root,
2542 NULL,
Venkat Gopalakrishnanc4093f92012-01-13 17:57:31 -08002543 &host_sender_no_lp_diag_rpc_test_ops);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002544
2545 test_ctx->debug.rmnet_small_packets_test =
2546 debugfs_create_file("180_rmnet_small_packets_test",
2547 S_IRUGO | S_IWUGO,
2548 test_ctx->debug.debug_root,
2549 NULL,
2550 &rmnet_small_packets_test_ops);
2551
2552 test_ctx->debug.rmnet_rtt_test =
2553 debugfs_create_file("190_rmnet_rtt_test",
2554 S_IRUGO | S_IWUGO,
2555 test_ctx->debug.debug_root,
2556 NULL,
2557 &rmnet_rtt_test_ops);
2558
Maya Erez241eb922011-10-23 10:51:26 +02002559 test_ctx->debug.csvt_rtt_test =
2560 debugfs_create_file("191_csvt_rtt_test",
2561 S_IRUGO | S_IWUGO,
2562 test_ctx->debug.debug_root,
2563 NULL,
2564 &csvt_rtt_test_ops);
2565
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002566 test_ctx->debug.modem_reset_rpc_test =
2567 debugfs_create_file("220_modem_reset_rpc_test",
2568 S_IRUGO | S_IWUGO,
2569 test_ctx->debug.debug_root,
2570 NULL,
2571 &modem_reset_rpc_test_ops);
2572
2573 test_ctx->debug.modem_reset_rmnet_test =
2574 debugfs_create_file("230_modem_reset_rmnet_test",
2575 S_IRUGO | S_IWUGO,
2576 test_ctx->debug.debug_root,
2577 NULL,
2578 &modem_reset_rmnet_test_ops);
2579
2580 test_ctx->debug.modem_reset_channels_4bit_dev_test =
2581 debugfs_create_file("240_modem_reset_channels_4bit_dev_test",
2582 S_IRUGO | S_IWUGO,
2583 test_ctx->debug.debug_root,
2584 NULL,
2585 &modem_reset_channels_4bit_dev_test_ops);
2586
2587 test_ctx->debug.modem_reset_channels_8bit_dev_test =
2588 debugfs_create_file("250_modem_reset_channels_8bit_dev_test",
2589 S_IRUGO | S_IWUGO,
2590 test_ctx->debug.debug_root,
2591 NULL,
2592 &modem_reset_channels_8bit_dev_test_ops);
2593
2594 test_ctx->debug.modem_reset_all_channels_test =
2595 debugfs_create_file("260_modem_reset_all_channels_test",
2596 S_IRUGO | S_IWUGO,
2597 test_ctx->debug.debug_root,
2598 NULL,
2599 &modem_reset_all_channels_test_ops);
2600
Maya Erezefafaa82011-09-21 12:41:28 +03002601 test_ctx->debug.open_close_test =
2602 debugfs_create_file("270_open_close_test",
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002603 S_IRUGO | S_IWUGO,
2604 test_ctx->debug.debug_root,
2605 NULL,
Maya Erezefafaa82011-09-21 12:41:28 +03002606 &open_close_test_ops);
Maya Ereze05fc4d2011-09-11 14:18:43 +03002607
2608 test_ctx->debug.open_close_dun_rmnet_test =
2609 debugfs_create_file("271_open_close_dun_rmnet_test",
2610 S_IRUGO | S_IWUGO,
2611 test_ctx->debug.debug_root,
2612 NULL,
2613 &open_close_dun_rmnet_test_ops);
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03002614
2615 test_ctx->debug.close_chan_lpm_test =
2616 debugfs_create_file("280_close_chan_lpm_test",
2617 S_IRUGO | S_IWUGO,
2618 test_ctx->debug.debug_root,
2619 NULL,
2620 &close_chan_lpm_test_ops);
2621
2622 test_ctx->debug.lpm_test_client_wakes_host_test =
2623 debugfs_create_file("600_lpm_test_client_wakes_host_test",
2624 S_IRUGO | S_IWUGO,
2625 test_ctx->debug.debug_root,
2626 NULL,
2627 &lpm_test_client_wakes_host_test_ops);
2628
2629 test_ctx->debug.lpm_test_host_wakes_client_test =
2630 debugfs_create_file("610_lpm_test_host_wakes_client_test",
2631 S_IRUGO | S_IWUGO,
2632 test_ctx->debug.debug_root,
2633 NULL,
2634 &lpm_test_host_wakes_client_test_ops);
2635
2636 test_ctx->debug.lpm_test_random_single_channel_test =
2637 debugfs_create_file("620_lpm_test_random_single_channel_test",
2638 S_IRUGO | S_IWUGO,
2639 test_ctx->debug.debug_root,
2640 NULL,
2641 &lpm_test_random_single_channel_test_ops);
2642
2643 test_ctx->debug.lpm_test_random_multi_channel_test =
2644 debugfs_create_file("630_lpm_test_random_multi_channel_test",
2645 S_IRUGO | S_IWUGO,
2646 test_ctx->debug.debug_root,
2647 NULL,
2648 &lpm_test_random_multi_channel_test_ops);
2649
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002650 if ((!test_ctx->debug.debug_dun_throughput) &&
2651 (!test_ctx->debug.debug_rmnt_throughput)) {
2652 debugfs_remove_recursive(test_ctx->debug.debug_root);
2653 test_ctx->debug.debug_root = NULL;
2654 return -ENOENT;
2655 }
2656 return 0;
2657}
2658
2659static void sdio_al_test_debugfs_cleanup(void)
2660{
2661 debugfs_remove(test_ctx->debug.debug_dun_throughput);
2662 debugfs_remove(test_ctx->debug.debug_rmnt_throughput);
2663 debugfs_remove(test_ctx->debug.debug_root);
2664}
2665#endif
2666
2667static int channel_name_to_id(char *name)
2668{
2669 pr_info(TEST_MODULE_NAME "%s: channel name %s\n",
2670 __func__, name);
2671
Maya Erez8afd564f2011-08-24 15:57:06 +03002672 if (!strncmp(name, "SDIO_RPC_TEST",
2673 strnlen("SDIO_RPC_TEST", CHANNEL_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002674 return SDIO_RPC;
Maya Erez8afd564f2011-08-24 15:57:06 +03002675 else if (!strncmp(name, "SDIO_QMI_TEST",
2676 strnlen("SDIO_QMI_TEST", TEST_CH_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002677 return SDIO_QMI;
Maya Erez8afd564f2011-08-24 15:57:06 +03002678 else if (!strncmp(name, "SDIO_RMNT_TEST",
2679 strnlen("SDIO_RMNT_TEST", TEST_CH_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002680 return SDIO_RMNT;
Maya Erez8afd564f2011-08-24 15:57:06 +03002681 else if (!strncmp(name, "SDIO_DIAG_TEST",
2682 strnlen("SDIO_DIAG", TEST_CH_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002683 return SDIO_DIAG;
Maya Erez8afd564f2011-08-24 15:57:06 +03002684 else if (!strncmp(name, "SDIO_DUN_TEST",
2685 strnlen("SDIO_DUN_TEST", TEST_CH_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002686 return SDIO_DUN;
Maya Erez8afd564f2011-08-24 15:57:06 +03002687 else if (!strncmp(name, "SDIO_SMEM_TEST",
2688 strnlen("SDIO_SMEM_TEST", TEST_CH_NAME_SIZE)))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002689 return SDIO_SMEM;
Maya Erez241eb922011-10-23 10:51:26 +02002690 else if (!strncmp(name, "SDIO_CSVT_TEST",
2691 strnlen("SDIO_CSVT_TEST", TEST_CH_NAME_SIZE)))
2692 return SDIO_CSVT;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002693 else
2694 return SDIO_MAX_CHANNELS;
2695
2696 return SDIO_MAX_CHANNELS;
2697}
2698
2699/**
Maya Erezefafaa82011-09-21 12:41:28 +03002700 * Allocate and add SDIO_SMEM platform device
2701 */
2702#ifdef CONFIG_MSM_SDIO_SMEM
2703static int add_sdio_smem(void)
2704{
2705 int ret = 0;
2706
2707 test_ctx->smem_pdev = platform_device_alloc("SDIO_SMEM", -1);
2708 ret = platform_device_add(test_ctx->smem_pdev);
2709 if (ret) {
2710 pr_err(TEST_MODULE_NAME ": platform_device_add failed, "
2711 "ret=%d\n", ret);
2712 return ret;
2713 }
2714 return 0;
2715}
2716#endif
2717
2718static int open_sdio_ch(struct test_channel *tch)
2719{
2720 int ret = 0;
2721
2722 if (!tch) {
2723 pr_err(TEST_MODULE_NAME ": %s NULL tch\n", __func__);
2724 return -EINVAL;
2725 }
2726
2727 if (!tch->ch_ready) {
2728 TEST_DBG(TEST_MODULE_NAME ":openning channel %s\n",
2729 tch->name);
2730 if (tch->ch_id == SDIO_SMEM) {
2731#ifdef CONFIG_MSM_SDIO_SMEM
2732 if (!test_ctx->smem_pdev)
2733 ret = add_sdio_smem();
2734 else
2735 ret = sdio_smem_open(test_ctx->sdio_smem);
2736 if (ret) {
2737 pr_err(TEST_MODULE_NAME
2738 ":openning channel %s failed\n",
2739 tch->name);
2740 tch->ch_ready = false;
2741 return -EINVAL;
2742 }
2743#endif
2744 } else {
2745 tch->ch_ready = true;
2746 ret = sdio_open(tch->name , &tch->ch, tch,
2747 notify);
2748 if (ret) {
2749 pr_err(TEST_MODULE_NAME
2750 ":openning channel %s failed\n",
2751 tch->name);
2752 tch->ch_ready = false;
2753 return -EINVAL;
2754 }
2755 }
2756 }
2757 return ret;
2758}
2759
2760static int close_sdio_ch(struct test_channel *tch)
2761{
2762 int ret = 0;
2763
2764 if (!tch) {
2765 pr_err(TEST_MODULE_NAME ": %s NULL tch\n", __func__);
2766 return -EINVAL;
2767 }
2768
2769 if (tch->ch_id == SDIO_SMEM) {
2770#ifdef CONFIG_MSM_SDIO_SMEM
2771 TEST_DBG(TEST_MODULE_NAME":%s closing channel %s",
2772 __func__, tch->name);
2773 ret = sdio_smem_unregister_client();
2774 test_ctx->smem_counter = 0;
2775#endif
2776 } else {
2777 ret = sdio_close(tch->ch);
2778 }
2779
2780 if (ret) {
2781 pr_err(TEST_MODULE_NAME":%s close channel %s"
2782 " failed\n", __func__, tch->name);
2783 } else {
2784 TEST_DBG(TEST_MODULE_NAME":%s close channel %s"
2785 " success\n", __func__, tch->name);
2786 tch->ch_ready = false;
2787 }
2788 return ret;
2789}
2790
2791/**
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002792 * Config message
2793 */
2794
2795static void send_config_msg(struct test_channel *test_ch)
2796{
2797 int ret = 0 ;
2798 u32 write_avail = 0;
2799 int size = sizeof(test_ch->config_msg);
2800
2801 pr_debug(TEST_MODULE_NAME "%s\n", __func__);
2802
2803 memcpy(test_ch->buf, (void *)&test_ch->config_msg, size);
2804
2805 if (test_ctx->exit_flag) {
2806 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
2807 return;
2808 }
2809
2810 pr_info(TEST_MODULE_NAME ":Sending the config message.\n");
2811
2812 /* wait for data ready event */
2813 write_avail = sdio_write_avail(test_ch->ch);
2814 pr_debug(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
2815 if (write_avail < size) {
2816 wait_event(test_ch->wait_q,
2817 atomic_read(&test_ch->tx_notify_count));
2818 atomic_dec(&test_ch->tx_notify_count);
2819 }
2820
2821 write_avail = sdio_write_avail(test_ch->ch);
2822 pr_debug(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
2823 if (write_avail < size) {
2824 pr_info(TEST_MODULE_NAME ":not enough write avail.\n");
2825 return;
2826 }
2827
2828 ret = sdio_write(test_ch->ch, test_ch->buf, size);
2829 if (ret)
2830 pr_err(TEST_MODULE_NAME ":%s sdio_write err=%d.\n",
2831 __func__, -ret);
2832 else
2833 pr_info(TEST_MODULE_NAME ":%s sent config_msg successfully.\n",
2834 __func__);
2835}
2836
2837/**
2838 * Loopback Test
2839 */
2840static void loopback_test(struct test_channel *test_ch)
2841{
2842 int ret = 0 ;
2843 u32 read_avail = 0;
2844 u32 write_avail = 0;
2845
2846 while (1) {
2847
2848 if (test_ctx->exit_flag) {
2849 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
2850 return;
2851 }
2852
2853 TEST_DBG(TEST_MODULE_NAME "--LOOPBACK WAIT FOR EVENT--.\n");
2854 /* wait for data ready event */
2855 wait_event(test_ch->wait_q,
2856 atomic_read(&test_ch->rx_notify_count));
2857 atomic_dec(&test_ch->rx_notify_count);
2858
2859 read_avail = sdio_read_avail(test_ch->ch);
2860 if (read_avail == 0)
2861 continue;
2862
2863
2864 write_avail = sdio_write_avail(test_ch->ch);
2865 if (write_avail < read_avail) {
2866 pr_info(TEST_MODULE_NAME
2867 ":not enough write avail.\n");
2868 continue;
2869 }
2870
2871 ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
2872 if (ret) {
2873 pr_info(TEST_MODULE_NAME
2874 ":worker, sdio_read err=%d.\n", -ret);
2875 continue;
2876 }
2877 test_ch->rx_bytes += read_avail;
2878
2879 TEST_DBG(TEST_MODULE_NAME ":worker total rx bytes = 0x%x.\n",
2880 test_ch->rx_bytes);
2881
2882
2883 ret = sdio_write(test_ch->ch,
2884 test_ch->buf, read_avail);
2885 if (ret) {
2886 pr_info(TEST_MODULE_NAME
2887 ":loopback sdio_write err=%d.\n",
2888 -ret);
2889 continue;
2890 }
2891 test_ch->tx_bytes += read_avail;
2892
2893 TEST_DBG(TEST_MODULE_NAME
2894 ":loopback total tx bytes = 0x%x.\n",
2895 test_ch->tx_bytes);
2896 } /* end of while */
2897}
2898
2899/**
2900 * Check if all tests completed
2901 */
2902static void check_test_completion(void)
2903{
2904 int i;
2905
2906 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
2907 struct test_channel *tch = test_ctx->test_ch_arr[i];
2908
2909 if ((!tch) || (!tch->is_used) || (!tch->ch_ready))
2910 continue;
2911 if (!tch->test_completed) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002912 pr_info(TEST_MODULE_NAME ": %s - Channel %s test is "
2913 "not completed", __func__, tch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002914 return;
2915 }
2916 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03002917 pr_info(TEST_MODULE_NAME ": %s - Test is completed", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002918 test_ctx->test_completed = 1;
2919 wake_up(&test_ctx->wait_q);
2920}
2921
2922static int pseudo_random_seed(unsigned int *seed_number)
2923{
2924 if (!seed_number)
2925 return 0;
2926
2927 *seed_number = (unsigned int)(((unsigned long)*seed_number *
2928 (unsigned long)1103515367) + 35757);
Maya Erezf204e692011-08-12 22:00:13 +03002929 return (int)((*seed_number / (64*1024)) % 500);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002930}
2931
Yaniv Gardi3e327762011-07-27 11:11:04 +03002932/* this function must be locked before accessing it */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002933static void lpm_test_update_entry(struct test_channel *tch,
2934 enum lpm_test_msg_type msg_type,
Yaniv Gardi3e327762011-07-27 11:11:04 +03002935 char *msg_name,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002936 int counter)
2937{
2938 u32 index = 0;
2939 static int print_full = 1;
Yaniv Gardi3e327762011-07-27 11:11:04 +03002940 struct sdio_test_device *test_device;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002941
2942 if (!tch) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03002943 pr_err(TEST_MODULE_NAME ": %s - NULL test channel\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002944 return;
2945 }
2946
Yaniv Gardi3e327762011-07-27 11:11:04 +03002947 test_device = tch->test_device;
2948
2949 if (!test_device) {
2950 pr_err(TEST_MODULE_NAME ": %s - NULL test device\n", __func__);
2951 return;
2952 }
2953
Maya Erez8afd564f2011-08-24 15:57:06 +03002954 if (!test_device->lpm_arr) {
2955 pr_err(TEST_MODULE_NAME ": %s - NULL lpm_arr\n", __func__);
2956 return;
2957 }
2958
Yaniv Gardi3e327762011-07-27 11:11:04 +03002959 if (test_device->next_avail_entry_in_array >=
2960 test_device->array_size) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002961 pr_err(TEST_MODULE_NAME ": %s - lpm array is full",
2962 __func__);
Yaniv Gardi3e327762011-07-27 11:11:04 +03002963
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002964 if (print_full) {
2965 print_hex_dump(KERN_INFO, TEST_MODULE_NAME ": lpm_arr:",
2966 0, 32, 2,
Yaniv Gardi3e327762011-07-27 11:11:04 +03002967 (void *)test_device->lpm_arr,
2968 sizeof(test_device->lpm_arr), false);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002969 print_full = 0;
2970 }
2971 return;
2972 }
2973
Yaniv Gardi3e327762011-07-27 11:11:04 +03002974 index = test_device->next_avail_entry_in_array;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002975 if ((msg_type == LPM_MSG_SEND) || (msg_type == LPM_MSG_REC))
Yaniv Gardi3e327762011-07-27 11:11:04 +03002976 test_device->lpm_arr[index].counter = counter;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002977 else
Yaniv Gardi3e327762011-07-27 11:11:04 +03002978 test_device->lpm_arr[index].counter = 0;
2979
2980 test_device->lpm_arr[index].msg_type = msg_type;
2981 memcpy(test_device->lpm_arr[index].msg_name, msg_name,
2982 LPM_MSG_NAME_SIZE);
2983 test_device->lpm_arr[index].current_ms =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002984 jiffies_to_msecs(get_jiffies_64());
2985
Yaniv Gardi3e327762011-07-27 11:11:04 +03002986 test_device->lpm_arr[index].read_avail_mask =
2987 test_device->read_avail_mask;
2988
2989 if ((msg_type == LPM_SLEEP) || (msg_type == LPM_WAKEUP))
2990 memcpy(test_device->lpm_arr[index].chan_name, "DEVICE ",
2991 CHANNEL_NAME_SIZE);
2992 else
2993 memcpy(test_device->lpm_arr[index].chan_name, tch->name,
2994 CHANNEL_NAME_SIZE);
2995
2996 test_device->next_avail_entry_in_array++;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002997}
2998
2999static int wait_for_result_msg(struct test_channel *test_ch)
3000{
3001 u32 read_avail = 0;
3002 int ret = 0;
3003
Yaniv Gardi3e327762011-07-27 11:11:04 +03003004 pr_info(TEST_MODULE_NAME ": %s - START, channel %s\n",
3005 __func__, test_ch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003006
3007 while (1) {
3008 read_avail = sdio_read_avail(test_ch->ch);
3009
3010 if (read_avail == 0) {
3011 pr_info(TEST_MODULE_NAME
3012 ": read_avail is 0 for chan %s\n",
3013 test_ch->name);
3014 wait_event(test_ch->wait_q,
3015 atomic_read(&test_ch->rx_notify_count));
3016 atomic_dec(&test_ch->rx_notify_count);
3017 continue;
3018 }
3019
3020 memset(test_ch->buf, 0x00, test_ch->buf_size);
3021
3022 ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
3023 if (ret) {
3024 pr_info(TEST_MODULE_NAME ": sdio_read for chan"
3025 "%s failed, err=%d.\n",
3026 test_ch->name, -ret);
3027 goto exit_err;
3028 }
3029
3030 if (test_ch->buf[0] != TEST_CONFIG_SIGNATURE) {
3031 pr_info(TEST_MODULE_NAME ": Not a test_result "
3032 "signature. expected 0x%x. received 0x%x "
3033 "for chan %s\n",
3034 TEST_CONFIG_SIGNATURE,
3035 test_ch->buf[0],
3036 test_ch->name);
3037 continue;
3038 } else {
3039 pr_info(TEST_MODULE_NAME ": Signature is "
Maya Erezb59ce2a2011-10-04 22:53:32 +02003040 "TEST_CONFIG_SIGNATURE as expected for"
3041 "channel %s\n", test_ch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003042 break;
3043 }
3044 }
3045
3046 return test_ch->buf[1];
3047
3048exit_err:
3049 return 0;
3050}
3051
Maya Erezb59ce2a2011-10-04 22:53:32 +02003052static void print_random_lpm_test_array(struct sdio_test_device *test_dev)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003053{
Maya Erezb59ce2a2011-10-04 22:53:32 +02003054 int i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003055
Yaniv Gardi3e327762011-07-27 11:11:04 +03003056 if (!test_dev) {
3057 pr_err(TEST_MODULE_NAME ": %s - NULL test device\n", __func__);
Maya Erezb59ce2a2011-10-04 22:53:32 +02003058 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003059 }
3060
Yaniv Gardi3e327762011-07-27 11:11:04 +03003061 for (i = 0 ; i < test_dev->next_avail_entry_in_array ; ++i) {
3062 if (i == 0)
3063 pr_err(TEST_MODULE_NAME ": index %4d, chan=%2s, "
3064 "code=%1d=%4s, msg#%1d, ms from before=-1, "
3065 "read_mask=0x%d, ms=%2u",
3066 i,
3067 test_dev->lpm_arr[i].chan_name,
3068 test_dev->lpm_arr[i].msg_type,
3069 test_dev->lpm_arr[i].msg_name,
3070 test_dev->lpm_arr[i].counter,
3071 test_dev->lpm_arr[i].read_avail_mask,
3072 test_dev->lpm_arr[i].current_ms);
3073 else
3074 pr_err(TEST_MODULE_NAME ": index "
3075 "%4d, %2s, code=%1d=%4s, msg#%1d, ms from "
3076 "before=%2u, read_mask=0x%d, ms=%2u",
3077 i,
3078 test_dev->lpm_arr[i].chan_name,
3079 test_dev->lpm_arr[i].msg_type,
3080 test_dev->lpm_arr[i].msg_name,
3081 test_dev->lpm_arr[i].counter,
3082 test_dev->lpm_arr[i].current_ms -
3083 test_dev->lpm_arr[i-1].current_ms,
3084 test_dev->lpm_arr[i].read_avail_mask,
3085 test_dev->lpm_arr[i].current_ms);
Maya Erezb59ce2a2011-10-04 22:53:32 +02003086
3087 udelay(1000);
3088 }
3089}
3090
3091static int check_random_lpm_test_array(struct sdio_test_device *test_dev)
3092{
3093 int i = 0, j = 0;
3094 unsigned int delta_ms = 0;
3095 int arr_ind = 0;
3096 int ret = 0;
3097 int notify_counter = 0;
3098 int sleep_counter = 0;
3099 int wakeup_counter = 0;
3100 int lpm_activity_counter = 0;
3101
3102 if (!test_dev) {
3103 pr_err(TEST_MODULE_NAME ": %s - NULL test device\n", __func__);
3104 return -ENODEV;
Yaniv Gardi3e327762011-07-27 11:11:04 +03003105 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003106
Yaniv Gardi3e327762011-07-27 11:11:04 +03003107 for (i = 0; i < test_dev->next_avail_entry_in_array; i++) {
3108 notify_counter = 0;
3109 sleep_counter = 0;
3110 wakeup_counter = 0;
3111
3112 if ((test_dev->lpm_arr[i].msg_type == LPM_MSG_SEND) ||
3113 (test_dev->lpm_arr[i].msg_type == LPM_MSG_REC)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003114 /* find the next message in the array */
Yaniv Gardi3e327762011-07-27 11:11:04 +03003115 arr_ind = test_dev->next_avail_entry_in_array;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003116 for (j = i+1; j < arr_ind; j++) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03003117 if ((test_dev->lpm_arr[j].msg_type ==
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003118 LPM_MSG_SEND) ||
Yaniv Gardi3e327762011-07-27 11:11:04 +03003119 (test_dev->lpm_arr[j].msg_type ==
3120 LPM_MSG_REC) ||
3121 (test_dev->lpm_arr[j].msg_type ==
3122 LPM_NOTIFY))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003123 break;
Yaniv Gardi3e327762011-07-27 11:11:04 +03003124 if (test_dev->lpm_arr[j].msg_type ==
3125 LPM_SLEEP)
3126 sleep_counter++;
3127 if (test_dev->lpm_arr[j].msg_type ==
3128 LPM_WAKEUP)
3129 wakeup_counter++;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003130 }
3131 if (j == arr_ind) {
Maya Erezb59ce2a2011-10-04 22:53:32 +02003132 ret = 0;
Yaniv Gardi3e327762011-07-27 11:11:04 +03003133 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003134 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03003135
3136 delta_ms = test_dev->lpm_arr[j].current_ms -
3137 test_dev->lpm_arr[i].current_ms;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003138 if (delta_ms < 30) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03003139 if ((sleep_counter == 0)
3140 && (wakeup_counter == 0)) {
3141 continue;
3142 } else {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003143 pr_err(TEST_MODULE_NAME "%s: lpm "
3144 "activity while delta is less "
Yaniv Gardi3e327762011-07-27 11:11:04 +03003145 "than 30, i=%d, j=%d, "
3146 "sleep_counter=%d, "
3147 "wakeup_counter=%d",
3148 __func__, i, j,
3149 sleep_counter, wakeup_counter);
Maya Erezb59ce2a2011-10-04 22:53:32 +02003150 ret = -ENODEV;
Yaniv Gardi3e327762011-07-27 11:11:04 +03003151 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003152 }
3153 } else {
Yaniv Gardi3e327762011-07-27 11:11:04 +03003154 if ((delta_ms > 90) &&
3155 (test_dev->lpm_arr[i].
3156 read_avail_mask == 0)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003157 if (j != i+3) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03003158 pr_err(TEST_MODULE_NAME
3159 "%s: unexpected "
3160 "lpm activity "
3161 "while delta is "
3162 "bigger than "
3163 "90, i=%d, "
3164 "j=%d, "
3165 "notify_counter"
3166 "=%d",
3167 __func__, i, j,
3168 notify_counter);
Maya Erezb59ce2a2011-10-04 22:53:32 +02003169 ret = -ENODEV;
Yaniv Gardi3e327762011-07-27 11:11:04 +03003170 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003171 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03003172 lpm_activity_counter++;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003173 }
3174 }
3175 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003176 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03003177
3178 pr_info(TEST_MODULE_NAME ": %s - lpm_activity_counter=%d",
3179 __func__, lpm_activity_counter);
3180
3181 return ret;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003182}
3183
3184static int lpm_test_main_task(void *ptr)
3185{
3186 u32 read_avail = 0;
3187 int last_msg_index = 0;
3188 struct test_channel *test_ch = (struct test_channel *)ptr;
Yaniv Gardi3e327762011-07-27 11:11:04 +03003189 struct sdio_test_device *test_dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003190 struct lpm_msg lpm_msg;
3191 int ret = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003192 int host_result = 0;
3193
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003194 if (!test_ch) {
3195 pr_err(TEST_MODULE_NAME ": %s - NULL channel\n", __func__);
3196 return -ENODEV;
3197 }
3198
Yaniv Gardi3e327762011-07-27 11:11:04 +03003199 pr_err(TEST_MODULE_NAME ": %s - STARTED. channel %s\n",
3200 __func__, test_ch->name);
3201
3202 test_dev = test_ch->test_device;
3203
3204 if (!test_dev) {
3205 pr_err(TEST_MODULE_NAME ": %s - NULL Test Device\n", __func__);
3206 return -ENODEV;
3207 }
3208
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003209 while (last_msg_index < test_ch->config_msg.num_packets - 1) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03003210
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003211 TEST_DBG(TEST_MODULE_NAME ": %s - "
3212 "IN LOOP last_msg_index=%d\n",
3213 __func__, last_msg_index);
3214
3215 read_avail = sdio_read_avail(test_ch->ch);
3216 if (read_avail == 0) {
3217 TEST_DBG(TEST_MODULE_NAME
3218 ":read_avail 0 for chan %s, "
3219 "wait for event\n",
3220 test_ch->name);
3221 wait_event(test_ch->wait_q,
3222 atomic_read(&test_ch->rx_notify_count));
3223 atomic_dec(&test_ch->rx_notify_count);
3224
3225 read_avail = sdio_read_avail(test_ch->ch);
3226 if (read_avail == 0) {
3227 pr_err(TEST_MODULE_NAME
3228 ":read_avail size %d for chan %s not as"
3229 " expected\n",
3230 read_avail, test_ch->name);
3231 continue;
3232 }
3233 }
3234
3235 memset(test_ch->buf, 0x00, sizeof(test_ch->buf));
3236
3237 ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
3238 if (ret) {
3239 pr_info(TEST_MODULE_NAME ":sdio_read for chan %s"
Yaniv Gardi3e327762011-07-27 11:11:04 +03003240 " err=%d.\n", test_ch->name, -ret);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003241 goto exit_err;
3242 }
3243
3244 memcpy((void *)&lpm_msg, test_ch->buf, sizeof(lpm_msg));
3245
Yaniv Gardi3e327762011-07-27 11:11:04 +03003246 /*
3247 * when reading from channel, we want to turn off the bit
3248 * mask that implies that there is pending data on that channel
3249 */
3250 if (test_ch->test_device != NULL) {
3251 spin_lock_irqsave(&test_dev->lpm_array_lock,
3252 test_dev->lpm_array_lock_flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003253
Yaniv Gardi3e327762011-07-27 11:11:04 +03003254 test_ch->notify_counter_per_chan--;
3255
3256 /*
3257 * if the channel has no pending data, turn off the
3258 * pending data bit mask of the channel
3259 */
3260 if (test_ch->notify_counter_per_chan == 0) {
3261 test_ch->test_device->read_avail_mask =
3262 test_ch->test_device->read_avail_mask &
3263 ~test_ch->channel_mask_id;
3264 }
3265
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003266 last_msg_index = lpm_msg.counter;
Yaniv Gardi3e327762011-07-27 11:11:04 +03003267 lpm_test_update_entry(test_ch,
3268 LPM_MSG_REC,
3269 "RECEIVE",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003270 last_msg_index);
Yaniv Gardi3e327762011-07-27 11:11:04 +03003271
3272 spin_unlock_irqrestore(&test_dev->lpm_array_lock,
3273 test_dev->lpm_array_lock_flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003274 }
3275 }
3276
Yaniv Gardi3e327762011-07-27 11:11:04 +03003277 pr_info(TEST_MODULE_NAME ":%s: Finished to recieve all (%d) "
3278 "packets from the modem %s. Waiting for result_msg",
3279 __func__, test_ch->config_msg.num_packets, test_ch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003280
3281 /* Wait for the resault message from the modem */
Yaniv Gardi3e327762011-07-27 11:11:04 +03003282 test_ch->modem_result_per_chan = wait_for_result_msg(test_ch);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003283
Yaniv Gardi3e327762011-07-27 11:11:04 +03003284 /*
3285 * the DEVICE modem result is a failure if one of the channels on
3286 * that device, got modem_result = 0. this is why we bitwise "AND" each
3287 * time another channel completes its task
3288 */
3289 test_dev->modem_result_per_dev &= test_ch->modem_result_per_chan;
3290
3291 /*
3292 * when reading from channel, we want to turn off the bit
3293 * mask that implies that there is pending data on that channel
3294 */
3295 spin_lock_irqsave(&test_dev->lpm_array_lock,
3296 test_dev->lpm_array_lock_flags);
3297
3298 test_dev->open_channels_counter_to_recv--;
3299
3300 /* turning off the read_avail bit of the channel */
3301 test_ch->test_device->read_avail_mask =
3302 test_ch->test_device->read_avail_mask &
3303 ~test_ch->channel_mask_id;
3304
3305 spin_unlock_irqrestore(&test_dev->lpm_array_lock,
3306 test_dev->lpm_array_lock_flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003307
3308 /* Wait for all the packets to be sent to the modem */
3309 while (1) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03003310 spin_lock_irqsave(&test_dev->lpm_array_lock,
3311 test_dev->lpm_array_lock_flags);
3312
3313 if (test_ch->next_index_in_sent_msg_per_chan >=
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003314 test_ch->config_msg.num_packets - 1) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03003315
3316 spin_unlock_irqrestore(&test_dev->lpm_array_lock,
3317 test_dev->lpm_array_lock_flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003318 break;
3319 } else {
3320 pr_info(TEST_MODULE_NAME ":%s: Didn't finished to send "
Yaniv Gardi3e327762011-07-27 11:11:04 +03003321 "all packets, "
3322 "next_index_in_sent_msg_per_chan = %d ",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003323 __func__,
Yaniv Gardi3e327762011-07-27 11:11:04 +03003324 test_ch->next_index_in_sent_msg_per_chan);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003325 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03003326 spin_unlock_irqrestore(&test_dev->lpm_array_lock,
3327 test_dev->lpm_array_lock_flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003328 msleep(60);
3329 }
3330
Maya Erezb59ce2a2011-10-04 22:53:32 +02003331 /*
3332 * if device has still open channels to test, then the test on the
3333 * device is still running but the test on current channel is completed
3334 */
Yaniv Gardi3e327762011-07-27 11:11:04 +03003335 if (test_dev->open_channels_counter_to_recv != 0 ||
3336 test_dev->open_channels_counter_to_send != 0) {
3337 test_ch->test_completed = 1;
Yaniv Gardi3e327762011-07-27 11:11:04 +03003338 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003339 } else {
Yaniv Gardi3e327762011-07-27 11:11:04 +03003340 test_ctx->number_of_active_devices--;
3341 sdio_al_unregister_lpm_cb(test_ch->sdio_al_device);
3342
3343 if (test_ch->test_type == SDIO_TEST_LPM_RANDOM)
3344 host_result = check_random_lpm_test_array(test_dev);
3345
Maya Erezb59ce2a2011-10-04 22:53:32 +02003346 if (host_result ||
3347 !test_dev->modem_result_per_dev ||
3348 test_ctx->runtime_debug)
3349 print_random_lpm_test_array(test_dev);
3350
3351 pr_info(TEST_MODULE_NAME ": %s - host_result=%d.(0 for "
3352 "SUCCESS) device_modem_result=%d (1 for SUCCESS)",
Yaniv Gardi3e327762011-07-27 11:11:04 +03003353 __func__, host_result, test_dev->modem_result_per_dev);
3354
3355 test_ch->test_completed = 1;
Maya Erezb59ce2a2011-10-04 22:53:32 +02003356 if (test_dev->modem_result_per_dev && !host_result) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03003357 pr_info(TEST_MODULE_NAME ": %s - Random LPM "
3358 "TEST_PASSED for device %d of %d\n",
3359 __func__,
3360 (test_ctx->max_number_of_devices-
3361 test_ctx->number_of_active_devices),
3362 test_ctx->max_number_of_devices);
3363 test_dev->final_result_per_dev = 1; /* PASSED */
3364 } else {
3365 pr_info(TEST_MODULE_NAME ": %s - Random LPM "
3366 "TEST_FAILED for device %d of %d\n",
3367 __func__,
3368 (test_ctx->max_number_of_devices-
3369 test_ctx->number_of_active_devices),
3370 test_ctx->max_number_of_devices);
3371 test_dev->final_result_per_dev = 0; /* FAILED */
3372 }
3373
Yaniv Gardi3e327762011-07-27 11:11:04 +03003374 check_test_completion();
3375
3376 kfree(test_ch->test_device->lpm_arr);
3377
3378 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003379 }
3380
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003381exit_err:
3382 pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
3383 test_ch->name);
3384 test_ch->test_completed = 1;
Yaniv Gardi3e327762011-07-27 11:11:04 +03003385 test_dev->open_channels_counter_to_recv--;
3386 test_dev->next_avail_entry_in_array = 0;
3387 test_ch->next_index_in_sent_msg_per_chan = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003388 test_ch->test_result = TEST_FAILED;
3389 check_test_completion();
3390 return -ENODEV;
3391}
3392
3393static int lpm_test_create_read_thread(struct test_channel *test_ch)
3394{
Yaniv Gardi3e327762011-07-27 11:11:04 +03003395 struct sdio_test_device *test_dev;
3396
3397 pr_info(TEST_MODULE_NAME ": %s - STARTED channel %s\n",
3398 __func__, test_ch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003399
3400 if (!test_ch) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03003401 pr_err(TEST_MODULE_NAME ": %s - NULL test channel\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003402 return -ENODEV;
3403 }
3404
Yaniv Gardi3e327762011-07-27 11:11:04 +03003405 test_dev = test_ch->test_device;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003406
Yaniv Gardi3e327762011-07-27 11:11:04 +03003407 if (!test_dev) {
3408 pr_err(TEST_MODULE_NAME ": %s - NULL test device\n", __func__);
3409 return -ENODEV;
3410 }
3411
3412 test_dev->lpm_test_task.task_name = SDIO_LPM_TEST;
3413
3414 test_dev->lpm_test_task.lpm_task =
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003415 kthread_create(lpm_test_main_task,
3416 (void *)(test_ch),
Yaniv Gardi3e327762011-07-27 11:11:04 +03003417 test_dev->lpm_test_task.task_name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003418
Yaniv Gardi3e327762011-07-27 11:11:04 +03003419 if (IS_ERR(test_dev->lpm_test_task.lpm_task)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003420 pr_err(TEST_MODULE_NAME ": %s - kthread_create() failed\n",
3421 __func__);
3422 return -ENOMEM;
3423 }
3424
Yaniv Gardi3e327762011-07-27 11:11:04 +03003425 wake_up_process(test_dev->lpm_test_task.lpm_task);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003426
3427 return 0;
3428}
3429
3430static void lpm_continuous_rand_test(struct test_channel *test_ch)
3431{
3432 unsigned int local_ms = 0;
3433 int ret = 0;
3434 unsigned int write_avail = 0;
Yaniv Gardi3e327762011-07-27 11:11:04 +03003435 struct sdio_test_device *test_dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003436
3437 pr_info(MODULE_NAME ": %s - STARTED\n", __func__);
3438
3439 if (!test_ch) {
3440 pr_err(TEST_MODULE_NAME ": %s - NULL channel\n", __func__);
3441 return;
3442 }
3443
Yaniv Gardi3e327762011-07-27 11:11:04 +03003444 test_dev = test_ch->test_device;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003445
Yaniv Gardi3e327762011-07-27 11:11:04 +03003446 if (!test_dev) {
3447 pr_err(TEST_MODULE_NAME ": %s - NULL Test Device\n", __func__);
3448 return;
3449 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003450
3451 ret = lpm_test_create_read_thread(test_ch);
3452 if (ret != 0) {
3453 pr_err(TEST_MODULE_NAME ": %s - failed to create lpm reading "
3454 "thread", __func__);
3455 }
3456
Yaniv Gardidacd7c32011-09-22 16:12:36 +03003457 while (1) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03003458
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003459 struct lpm_msg msg;
3460 u32 ret = 0;
3461
Yaniv Gardi3e327762011-07-27 11:11:04 +03003462 /* sleeping period is dependent on number of open channels */
Maya Erezf204e692011-08-12 22:00:13 +03003463 test_ch->config_msg.test_param =
3464 test_ctx->lpm_pseudo_random_seed;
Yaniv Gardi3e327762011-07-27 11:11:04 +03003465
3466 local_ms = test_dev->open_channels_counter_to_send *
Maya Erezf204e692011-08-12 22:00:13 +03003467 test_ctx->lpm_pseudo_random_seed;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003468 TEST_DBG(TEST_MODULE_NAME ":%s: SLEEPING for %d ms",
3469 __func__, local_ms);
3470 msleep(local_ms);
3471
Yaniv Gardi3e327762011-07-27 11:11:04 +03003472 msg.counter = test_ch->next_index_in_sent_msg_per_chan;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003473 msg.signature = LPM_TEST_CONFIG_SIGNATURE;
3474 msg.reserve1 = 0;
3475 msg.reserve2 = 0;
3476
3477 /* wait for data ready event */
3478 write_avail = sdio_write_avail(test_ch->ch);
3479 pr_debug(TEST_MODULE_NAME ": %s: write_avail=%d\n",
3480 __func__, write_avail);
3481 if (write_avail < sizeof(msg)) {
3482 wait_event(test_ch->wait_q,
3483 atomic_read(&test_ch->tx_notify_count));
3484 atomic_dec(&test_ch->tx_notify_count);
3485 }
3486
3487 write_avail = sdio_write_avail(test_ch->ch);
3488 if (write_avail < sizeof(msg)) {
3489 pr_info(TEST_MODULE_NAME ": %s: not enough write "
3490 "avail.\n", __func__);
3491 break;
3492 }
3493
3494 ret = sdio_write(test_ch->ch, (u32 *)&msg, sizeof(msg));
3495 if (ret)
3496 pr_err(TEST_MODULE_NAME ":%s: sdio_write err=%d.\n",
3497 __func__, -ret);
3498
Yaniv Gardi3e327762011-07-27 11:11:04 +03003499 TEST_DBG(TEST_MODULE_NAME ": %s: for chan %s, write, "
3500 "msg # %d\n",
3501 __func__,
3502 test_ch->name,
3503 test_ch->next_index_in_sent_msg_per_chan);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003504
Yaniv Gardi3e327762011-07-27 11:11:04 +03003505 if (test_ch->test_type == SDIO_TEST_LPM_RANDOM) {
3506 spin_lock_irqsave(&test_dev->lpm_array_lock,
3507 test_dev->lpm_array_lock_flags);
3508 lpm_test_update_entry(test_ch, LPM_MSG_SEND,
3509 "SEND ",
3510 test_ch->
3511 next_index_in_sent_msg_per_chan);
3512
3513 test_ch->next_index_in_sent_msg_per_chan++;
3514
Yaniv Gardidacd7c32011-09-22 16:12:36 +03003515 if (test_ch->next_index_in_sent_msg_per_chan ==
3516 test_ch->config_msg.num_packets) {
3517 spin_unlock_irqrestore(
3518 &test_dev->lpm_array_lock,
3519 test_dev->lpm_array_lock_flags);
3520 break;
3521 }
3522
Yaniv Gardi3e327762011-07-27 11:11:04 +03003523 spin_unlock_irqrestore(&test_dev->lpm_array_lock,
3524 test_dev->lpm_array_lock_flags);
3525 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003526 }
3527
Yaniv Gardi3e327762011-07-27 11:11:04 +03003528 spin_lock_irqsave(&test_dev->lpm_array_lock,
3529 test_dev->lpm_array_lock_flags);
3530 test_dev->open_channels_counter_to_send--;
3531 spin_unlock_irqrestore(&test_dev->lpm_array_lock,
3532 test_dev->lpm_array_lock_flags);
3533
3534 pr_info(TEST_MODULE_NAME ": %s: - Finished to send all (%d) "
3535 "packets to the modem on channel %s",
3536 __func__, test_ch->config_msg.num_packets, test_ch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003537
3538 return;
3539}
3540
3541static void lpm_test(struct test_channel *test_ch)
3542{
Yaniv Gardi3e327762011-07-27 11:11:04 +03003543 pr_info(TEST_MODULE_NAME ": %s - START channel %s\n", __func__,
3544 test_ch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003545
3546 if (!test_ch) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03003547 pr_err(TEST_MODULE_NAME ": %s - NULL test channel\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003548 return;
3549 }
3550
Yaniv Gardi3e327762011-07-27 11:11:04 +03003551 test_ch->modem_result_per_chan = wait_for_result_msg(test_ch);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003552 pr_debug(TEST_MODULE_NAME ": %s - delete the timeout timer\n",
3553 __func__);
3554 del_timer_sync(&test_ch->timeout_timer);
3555
Yaniv Gardi3e327762011-07-27 11:11:04 +03003556 if (test_ch->modem_result_per_chan == 0) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003557 pr_err(TEST_MODULE_NAME ": LPM TEST - Client didn't sleep. "
3558 "Result Msg - is_successful=%d\n", test_ch->buf[1]);
3559 goto exit_err;
3560 } else {
3561 pr_info(TEST_MODULE_NAME ": %s -"
3562 "LPM 9K WAS SLEEPING - PASS\n", __func__);
3563 if (test_ch->test_result == TEST_PASSED) {
3564 pr_info(TEST_MODULE_NAME ": LPM TEST_PASSED\n");
3565 test_ch->test_completed = 1;
3566 check_test_completion();
3567 } else {
3568 pr_err(TEST_MODULE_NAME ": LPM TEST - Host didn't "
3569 "sleep. Client slept\n");
3570 goto exit_err;
3571 }
3572 }
3573
3574 return;
3575
3576exit_err:
3577 pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
3578 test_ch->name);
3579 test_ch->test_completed = 1;
3580 test_ch->test_result = TEST_FAILED;
3581 check_test_completion();
3582 return;
3583}
3584
3585
3586/**
3587 * LPM Test while the host wakes up the modem
3588 */
3589static void lpm_test_host_waker(struct test_channel *test_ch)
3590{
3591 pr_info(TEST_MODULE_NAME ": %s - START\n", __func__);
3592 wait_event(test_ch->wait_q, atomic_read(&test_ch->wakeup_client));
3593 atomic_set(&test_ch->wakeup_client, 0);
3594
3595 pr_info(TEST_MODULE_NAME ": %s - Sending the config_msg to wakeup "
3596 " the client\n", __func__);
3597 send_config_msg(test_ch);
3598
3599 lpm_test(test_ch);
3600}
3601
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003602/**
3603 * Writes number of packets into test channel
3604 * @test_ch: test channel control struct
3605 * @burst_size: number of packets to send
3606 */
3607static int write_packet_burst(struct test_channel *test_ch,
3608 int burst_size)
3609{
3610 int ret = 0;
3611 int packet_count = 0;
3612 unsigned int random_num = 0;
3613 int size = test_ch->packet_length; /* first packet size */
3614 u32 write_avail = 0;
3615
3616 while (packet_count < burst_size) {
3617 /* wait for data ready event */
3618 write_avail = sdio_write_avail(test_ch->ch);
3619 TEST_DBG(TEST_MODULE_NAME ":%s write_avail=%d,size=%d on chan"
3620 " %s\n", __func__,
3621 write_avail, size, test_ch->name);
3622 if (write_avail < size) {
3623 TEST_DBG(TEST_MODULE_NAME ":%s wait for event on"
3624 " chan %s\n", __func__, test_ch->name);
3625 wait_event(test_ch->wait_q,
3626 atomic_read(&test_ch->tx_notify_count));
3627 atomic_dec(&test_ch->tx_notify_count);
3628 }
3629 write_avail = sdio_write_avail(test_ch->ch);
3630 if (write_avail < size) {
3631 pr_info(TEST_MODULE_NAME ":%s not enough write"
3632 " avail %d, need %d on chan %s\n",
3633 __func__, write_avail, size,
3634 test_ch->name);
3635 continue;
3636 }
3637 ret = sdio_write(test_ch->ch, test_ch->buf, size);
3638 if (ret) {
3639 pr_err(TEST_MODULE_NAME ":%s sdio_write "
3640 "failed (%d) on chan %s\n", __func__,
3641 ret, test_ch->name);
3642 break;
3643 }
3644 udelay(1000); /*low bus usage while running number of channels*/
3645 TEST_DBG(TEST_MODULE_NAME ":%s() successfully write %d bytes"
3646 ", packet_count=%d on chan %s\n", __func__,
3647 size, packet_count, test_ch->name);
3648 test_ch->tx_bytes += size;
3649 packet_count++;
3650 /* get next packet size */
3651 random_num = get_random_int();
3652 size = (random_num % test_ch->packet_length) + 1;
3653 }
3654 return ret;
3655}
Maya Ereze05fc4d2011-09-11 14:18:43 +03003656
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003657/**
3658 * Reads packet from test channel and checks that packet number
3659 * encoded into the packet is equal to packet_counter
Maya Ereze05fc4d2011-09-11 14:18:43 +03003660 * This function is applicable for packet mode channels only
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003661 *
3662 * @test_ch: test channel
3663 * @size: expected packet size
3664 * @packet_counter: number to validate readed packet
3665 */
Maya Ereze05fc4d2011-09-11 14:18:43 +03003666static int read_data_from_packet_ch(struct test_channel *test_ch,
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003667 unsigned int size,
3668 int packet_counter)
3669{
3670 u32 read_avail = 0;
3671 int ret = 0;
3672
Maya Ereze05fc4d2011-09-11 14:18:43 +03003673 if (!test_ch || !test_ch->ch) {
3674 pr_err(TEST_MODULE_NAME
3675 ":%s: NULL channel\n", __func__);
3676 return -EINVAL;
3677 }
3678
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003679 if (!test_ch->ch->is_packet_mode) {
3680 pr_err(TEST_MODULE_NAME
3681 ":%s:not packet mode ch %s\n",
3682 __func__, test_ch->name);
3683 return -EINVAL;
3684 }
3685 read_avail = sdio_read_avail(test_ch->ch);
3686 /* wait for read data ready event */
3687 if (read_avail < size) {
3688 TEST_DBG(TEST_MODULE_NAME ":%s() wait for rx data on "
3689 "chan %s\n", __func__, test_ch->name);
3690 wait_event(test_ch->wait_q,
3691 atomic_read(&test_ch->rx_notify_count));
3692 atomic_dec(&test_ch->rx_notify_count);
3693 }
3694 read_avail = sdio_read_avail(test_ch->ch);
3695 TEST_DBG(TEST_MODULE_NAME ":%s read_avail=%d bytes on chan %s\n",
3696 __func__, read_avail, test_ch->name);
3697
3698 if (read_avail != size) {
3699 pr_err(TEST_MODULE_NAME
3700 ":read_avail size %d for chan %s not as "
3701 "expected size %d\n",
3702 read_avail, test_ch->name, size);
3703 return -EINVAL;
3704 }
3705
3706 ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
3707 if (ret) {
3708 pr_err(TEST_MODULE_NAME ":%s() sdio_read for chan %s (%d)\n",
3709 __func__, test_ch->name, -ret);
3710 return ret;
3711 }
3712 if ((test_ch->buf[0] != packet_counter) && (size != 1)) {
3713 pr_err(TEST_MODULE_NAME ":Read WRONG DATA"
3714 " for chan %s, size=%d\n",
3715 test_ch->name, size);
3716 return -EINVAL;
3717 }
3718 return 0;
3719}
3720
Maya Ereze05fc4d2011-09-11 14:18:43 +03003721
3722/**
3723 * Reads packet from test channel and checks that packet number
3724 * encoded into the packet is equal to packet_counter
3725 * This function is applicable for streaming mode channels only
3726 *
3727 * @test_ch: test channel
3728 * @size: expected packet size
3729 * @packet_counter: number to validate readed packet
3730 */
3731static int read_data_from_stream_ch(struct test_channel *test_ch,
3732 unsigned int size,
3733 int packet_counter)
3734{
3735 u32 read_avail = 0;
3736 int ret = 0;
3737
3738 if (!test_ch || !test_ch->ch) {
3739 pr_err(TEST_MODULE_NAME
3740 ":%s: NULL channel\n", __func__);
3741 return -EINVAL;
3742 }
3743
3744 if (test_ch->ch->is_packet_mode) {
3745 pr_err(TEST_MODULE_NAME
3746 ":%s:not streaming mode ch %s\n",
3747 __func__, test_ch->name);
3748 return -EINVAL;
3749 }
3750 read_avail = sdio_read_avail(test_ch->ch);
3751 /* wait for read data ready event */
3752 if (read_avail < size) {
3753 TEST_DBG(TEST_MODULE_NAME ":%s() wait for rx data on "
3754 "chan %s\n", __func__, test_ch->name);
3755 wait_event(test_ch->wait_q,
3756 atomic_read(&test_ch->rx_notify_count));
3757 atomic_dec(&test_ch->rx_notify_count);
3758 }
3759 read_avail = sdio_read_avail(test_ch->ch);
3760 TEST_DBG(TEST_MODULE_NAME ":%s read_avail=%d bytes on chan %s\n",
3761 __func__, read_avail, test_ch->name);
3762
3763 if (read_avail < size) {
3764 pr_err(TEST_MODULE_NAME
3765 ":read_avail size %d for chan %s not as "
3766 "expected size %d\n",
3767 read_avail, test_ch->name, size);
3768 return -EINVAL;
3769 }
3770
3771 ret = sdio_read(test_ch->ch, test_ch->buf, size + A2_HEADER_OVERHEAD);
3772 if (ret) {
3773 pr_err(TEST_MODULE_NAME ":%s() sdio_read for chan %s (%d)\n",
3774 __func__, test_ch->name, -ret);
3775 return ret;
3776 }
3777 if ((test_ch->buf[A2_HEADER_OVERHEAD/4] != packet_counter) &&
3778 (size != 1)) {
3779 pr_err(TEST_MODULE_NAME ":Read WRONG DATA"
3780 " for chan %s, size=%d, packet_counter=%d\n",
3781 test_ch->name, size, packet_counter);
3782 print_hex_dump(KERN_INFO, TEST_MODULE_NAME ": rmnet:",
3783 0, 32, 2,
3784 (void *)test_ch->buf,
3785 size + A2_HEADER_OVERHEAD, false);
3786 return -EINVAL;
3787 }
3788 return 0;
3789}
3790
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003791/**
Maya Erezefafaa82011-09-21 12:41:28 +03003792 * Test close channel feature for SDIO_SMEM channel:
3793 * close && re-open the SDIO_SMEM channel.
3794 */
3795#ifdef CONFIG_MSM_SDIO_SMEM
3796static void open_close_smem_test(struct test_channel *test_ch)
3797{
3798 int i = 0;
3799 int ret = 0;
3800
3801 pr_info(TEST_MODULE_NAME ":%s\n", __func__);
3802
3803 for (i = 0; i < 100 ; ++i) {
3804 ret = close_sdio_ch(test_ch);
3805 if (ret) {
3806 pr_err(TEST_MODULE_NAME ":%s close_sdio_ch for ch %s"
3807 " failed\n",
3808 __func__, test_ch->name);
3809 goto exit_err;
3810 }
3811 ret = open_sdio_ch(test_ch);
3812 if (ret) {
3813 pr_err(TEST_MODULE_NAME ":%s open_sdio_ch for ch %s "
3814 " failed\n",
3815 __func__, test_ch->name);
3816 goto exit_err;
3817 }
3818 }
3819
3820 pr_info(TEST_MODULE_NAME ":%s TEST PASS for chan %s.\n", __func__,
3821 test_ch->name);
3822 test_ch->test_completed = 1;
3823 test_ch->test_result = TEST_PASSED;
3824 check_test_completion();
3825 return;
3826exit_err:
3827 pr_info(TEST_MODULE_NAME ":%s TEST FAIL for chan %s.\n", __func__,
3828 test_ch->name);
3829 test_ch->test_completed = 1;
3830 test_ch->test_result = TEST_FAILED;
3831 check_test_completion();
3832 return;
3833}
3834#endif
3835
3836/**
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003837 * Test close channel feature:
3838 * 1. write random packet number into channel
3839 * 2. read some data from channel (do this only for second half of
3840 * requested packets to send).
3841 * 3. close && re-open then repeat 1.
3842 *
3843 * Total packets to send: test_ch->config_msg.num_packets.
3844 * Burst size is random in [1..test_ch->max_burst_size] range
3845 * Packet size is random in [1..test_ch->packet_length]
3846 */
3847static void open_close_test(struct test_channel *test_ch)
3848{
3849 int ret = 0;
3850 u32 read_avail = 0;
3851 int total_packet_count = 0;
Maya Ereze05fc4d2011-09-11 14:18:43 +03003852 int size = 0;
3853 u16 *buf16 = NULL;
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003854 int i;
3855 int max_packet_count = 0;
3856 unsigned int random_num = 0;
Maya Ereze05fc4d2011-09-11 14:18:43 +03003857 int curr_burst_size = 0;
3858
3859 if (!test_ch || !test_ch->ch) {
3860 pr_err(TEST_MODULE_NAME ":%s NULL channel\n",
3861 __func__);
3862 return;
3863 }
3864
3865 curr_burst_size = test_ch->max_burst_size;
3866 size = test_ch->packet_length;
3867 buf16 = (u16 *) test_ch->buf;
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003868
3869 /* the test sends configured number of packets in
3870 2 portions: first without reading between write bursts,
3871 second with it */
3872 max_packet_count = test_ch->config_msg.num_packets / 2;
3873
3874 pr_info(TEST_MODULE_NAME ":%s channel %s, total packets:%d,"
3875 " max packet size %d, max burst size:%d\n",
3876 __func__, test_ch->name,
3877 test_ch->config_msg.num_packets, test_ch->packet_length,
3878 test_ch->max_burst_size);
3879 for (i = 0 ; i < size / 2 ; i++)
3880 buf16[i] = (u16) (i & 0xFFFF);
3881
3882 for (i = 0; i < 2 ; i++) {
3883 total_packet_count = 0;
3884 while (total_packet_count < max_packet_count) {
3885 if (test_ctx->exit_flag) {
3886 pr_info(TEST_MODULE_NAME ":%s exit test\n",
3887 __func__);
3888 return;
3889 }
3890 test_ch->buf[0] = total_packet_count;
3891 random_num = get_random_int();
3892 curr_burst_size = (random_num %
3893 test_ch->max_burst_size) + 1;
3894
3895 /* limit burst size to send
3896 * no more than configured packets */
3897 if (curr_burst_size + total_packet_count >
3898 max_packet_count) {
3899 curr_burst_size = max_packet_count -
3900 total_packet_count;
3901 }
3902 TEST_DBG(TEST_MODULE_NAME ":%s Current burst size:%d"
3903 " on chan %s\n", __func__,
3904 curr_burst_size, test_ch->name);
3905 ret = write_packet_burst(test_ch, curr_burst_size);
3906 if (ret) {
3907 pr_err(TEST_MODULE_NAME ":%s write burst failed (%d), ch %s\n",
3908 __func__, ret, test_ch->name);
3909 goto exit_err;
3910 }
3911 if (i > 0) {
3912 /* read from channel */
Maya Ereze05fc4d2011-09-11 14:18:43 +03003913 if (test_ch->ch->is_packet_mode)
3914 ret = read_data_from_packet_ch(test_ch,
3915 size,
3916 total_packet_count);
3917 else
3918 ret = read_data_from_stream_ch(test_ch,
3919 size,
3920 total_packet_count);
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003921 if (ret) {
3922 pr_err(TEST_MODULE_NAME ":%s read"
3923 " failed:%d, chan %s\n",
3924 __func__, ret,
3925 test_ch->name);
3926 goto exit_err;
3927 }
3928 }
3929 TEST_DBG(TEST_MODULE_NAME ":%s before close, ch %s\n",
3930 __func__, test_ch->name);
Maya Erezefafaa82011-09-21 12:41:28 +03003931 ret = close_sdio_ch(test_ch);
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003932 if (ret) {
3933 pr_err(TEST_MODULE_NAME":%s close channel %s"
3934 " failed (%d)\n",
3935 __func__, test_ch->name, ret);
3936 goto exit_err;
3937 } else {
3938 TEST_DBG(TEST_MODULE_NAME":%s close channel %s"
3939 " success\n", __func__,
3940 test_ch->name);
3941 total_packet_count += curr_burst_size;
3942 atomic_set(&test_ch->rx_notify_count, 0);
3943 atomic_set(&test_ch->tx_notify_count, 0);
3944 atomic_set(&test_ch->any_notify_count, 0);
3945 }
3946 TEST_DBG(TEST_MODULE_NAME ":%s before open, ch %s\n",
3947 __func__, test_ch->name);
Maya Erezefafaa82011-09-21 12:41:28 +03003948 ret = open_sdio_ch(test_ch);
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03003949 if (ret) {
3950 pr_err(TEST_MODULE_NAME":%s open channel %s"
3951 " failed (%d)\n",
3952 __func__, test_ch->name, ret);
3953 goto exit_err;
3954 } else {
3955 read_avail = sdio_read_avail(test_ch->ch);
3956 if (read_avail > 0) {
3957 pr_err(TEST_MODULE_NAME": after open"
3958 " ch %s read_availis not zero"
3959 " (%d bytes)\n",
3960 test_ch->name, read_avail);
3961 goto exit_err;
3962 }
3963 }
3964 TEST_DBG(TEST_MODULE_NAME ":%s total tx = %d,"
3965 " packet# = %d, size = %d for ch %s\n",
3966 __func__, test_ch->tx_bytes,
3967 total_packet_count, size,
3968 test_ch->name);
3969 } /* end of while */
3970 }
3971 pr_info(TEST_MODULE_NAME ":%s Test end: total rx bytes = 0x%x,"
3972 " total tx bytes = 0x%x for chan %s\n", __func__,
3973 test_ch->rx_bytes, test_ch->tx_bytes, test_ch->name);
3974 pr_info(TEST_MODULE_NAME ":%s TEST PASS for chan %s.\n", __func__,
3975 test_ch->name);
3976 test_ch->test_completed = 1;
3977 test_ch->test_result = TEST_PASSED;
3978 check_test_completion();
3979 return;
3980exit_err:
3981 pr_info(TEST_MODULE_NAME ":%s TEST FAIL for chan %s.\n", __func__,
3982 test_ch->name);
3983 test_ch->test_completed = 1;
3984 test_ch->test_result = TEST_FAILED;
3985 check_test_completion();
3986 return;
3987}
3988
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003989/**
3990 * sender Test
3991 */
3992static void sender_test(struct test_channel *test_ch)
3993{
3994 int ret = 0 ;
3995 u32 read_avail = 0;
3996 u32 write_avail = 0;
3997 int packet_count = 0;
3998 int size = 512;
3999 u16 *buf16 = (u16 *) test_ch->buf;
4000 int i;
4001 int max_packet_count = 10000;
4002 int random_num = 0;
4003
4004 max_packet_count = test_ch->config_msg.num_packets;
4005
4006 for (i = 0 ; i < size / 2 ; i++)
4007 buf16[i] = (u16) (i & 0xFFFF);
4008
4009
4010 pr_info(TEST_MODULE_NAME
4011 ":SENDER TEST START for chan %s\n", test_ch->name);
4012
4013 while (packet_count < max_packet_count) {
4014
4015 if (test_ctx->exit_flag) {
4016 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
4017 return;
4018 }
4019
4020 random_num = get_random_int();
4021 size = (random_num % test_ch->packet_length) + 1;
4022
4023 TEST_DBG(TEST_MODULE_NAME "SENDER WAIT FOR EVENT for chan %s\n",
4024 test_ch->name);
4025
4026 /* wait for data ready event */
4027 write_avail = sdio_write_avail(test_ch->ch);
4028 TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
4029 if (write_avail < size) {
4030 wait_event(test_ch->wait_q,
4031 atomic_read(&test_ch->tx_notify_count));
4032 atomic_dec(&test_ch->tx_notify_count);
4033 }
4034
4035 write_avail = sdio_write_avail(test_ch->ch);
4036 TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
4037 if (write_avail < size) {
4038 pr_info(TEST_MODULE_NAME ":not enough write avail.\n");
4039 continue;
4040 }
4041
4042 test_ch->buf[0] = packet_count;
4043
4044 ret = sdio_write(test_ch->ch, test_ch->buf, size);
4045 if (ret) {
4046 pr_info(TEST_MODULE_NAME ":sender sdio_write err=%d.\n",
4047 -ret);
4048 goto exit_err;
4049 }
4050
4051 /* wait for read data ready event */
4052 TEST_DBG(TEST_MODULE_NAME ":sender wait for rx data for "
4053 "chan %s\n",
4054 test_ch->name);
4055 read_avail = sdio_read_avail(test_ch->ch);
4056 wait_event(test_ch->wait_q,
4057 atomic_read(&test_ch->rx_notify_count));
4058 atomic_dec(&test_ch->rx_notify_count);
4059
4060 read_avail = sdio_read_avail(test_ch->ch);
4061
4062 if (read_avail != size) {
4063 pr_info(TEST_MODULE_NAME
4064 ":read_avail size %d for chan %s not as "
4065 "expected size %d.\n",
4066 read_avail, test_ch->name, size);
4067 goto exit_err;
4068 }
4069
4070 memset(test_ch->buf, 0x00, size);
4071
4072 ret = sdio_read(test_ch->ch, test_ch->buf, size);
4073 if (ret) {
4074 pr_info(TEST_MODULE_NAME ":sender sdio_read for chan %s"
4075 " err=%d.\n",
4076 test_ch->name, -ret);
4077 goto exit_err;
4078 }
4079
4080
4081 if ((test_ch->buf[0] != packet_count) && (size != 1)) {
4082 pr_info(TEST_MODULE_NAME ":sender sdio_read WRONG DATA"
4083 " for chan %s, size=%d\n",
4084 test_ch->name, size);
4085 goto exit_err;
4086 }
4087
4088 test_ch->tx_bytes += size;
4089 test_ch->rx_bytes += size;
4090 packet_count++;
4091
4092 TEST_DBG(TEST_MODULE_NAME
4093 ":sender total rx bytes = 0x%x , packet#=%d, size=%d"
4094 " for chan %s\n",
4095 test_ch->rx_bytes, packet_count, size, test_ch->name);
4096 TEST_DBG(TEST_MODULE_NAME
4097 ":sender total tx bytes = 0x%x , packet#=%d, size=%d"
4098 " for chan %s\n",
4099 test_ch->tx_bytes, packet_count, size, test_ch->name);
4100
4101 } /* end of while */
4102
4103 pr_info(TEST_MODULE_NAME
4104 ":SENDER TEST END: total rx bytes = 0x%x, "
4105 " total tx bytes = 0x%x for chan %s\n",
4106 test_ch->rx_bytes, test_ch->tx_bytes, test_ch->name);
4107
4108 pr_info(TEST_MODULE_NAME ": TEST PASS for chan %s.\n",
4109 test_ch->name);
4110 test_ch->test_completed = 1;
4111 test_ch->test_result = TEST_PASSED;
4112 check_test_completion();
4113 return;
4114
4115exit_err:
4116 pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
4117 test_ch->name);
4118 test_ch->test_completed = 1;
4119 test_ch->test_result = TEST_FAILED;
4120 check_test_completion();
4121 return;
4122}
4123
4124/**
4125 * A2 Perf Test
4126 */
4127static void a2_performance_test(struct test_channel *test_ch)
4128{
4129 int ret = 0 ;
4130 u32 read_avail = 0;
4131 u32 write_avail = 0;
4132 int tx_packet_count = 0;
4133 int rx_packet_count = 0;
4134 int size = 0;
4135 u16 *buf16 = (u16 *) test_ch->buf;
4136 int i;
4137 int total_bytes = 0;
4138 int max_packets = 10000;
4139 u32 packet_size = test_ch->buf_size;
4140 int rand_size = 0;
4141
4142 u64 start_jiffy, end_jiffy, delta_jiffies;
4143 unsigned int time_msec = 0;
4144 u32 throughput = 0;
4145
4146 max_packets = test_ch->config_msg.num_packets;
4147 packet_size = test_ch->packet_length;
4148
4149 for (i = 0; i < packet_size / 2; i++)
4150 buf16[i] = (u16) (i & 0xFFFF);
4151
4152 pr_info(TEST_MODULE_NAME ": A2 PERFORMANCE TEST START for chan %s\n",
4153 test_ch->name);
4154
4155 start_jiffy = get_jiffies_64(); /* read the current time */
4156
4157 while (tx_packet_count < max_packets) {
4158
4159 if (test_ctx->exit_flag) {
4160 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
4161 return;
4162 }
4163
4164 if (test_ch->random_packet_size) {
4165 rand_size = get_random_int();
4166 packet_size = (rand_size % test_ch->packet_length) + 1;
4167 if (packet_size < A2_MIN_PACKET_SIZE)
4168 packet_size = A2_MIN_PACKET_SIZE;
4169 }
4170
4171 /* wait for data ready event */
4172 /* use a func to avoid compiler optimizations */
4173 write_avail = sdio_write_avail(test_ch->ch);
4174 read_avail = sdio_read_avail(test_ch->ch);
4175 TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d, "
4176 "read_avail=%d for chan %s\n",
4177 test_ch->name, write_avail, read_avail,
4178 test_ch->name);
4179 if ((write_avail == 0) && (read_avail == 0)) {
4180 wait_event(test_ch->wait_q,
4181 atomic_read(&test_ch->any_notify_count));
4182 atomic_set(&test_ch->any_notify_count, 0);
4183 }
4184
4185 write_avail = sdio_write_avail(test_ch->ch);
4186 TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d\n",
4187 test_ch->name, write_avail);
4188 if (write_avail > 0) {
4189 size = min(packet_size, write_avail) ;
4190 TEST_DBG(TEST_MODULE_NAME ":tx size = %d for chan %s\n",
4191 size, test_ch->name);
4192 test_ch->buf[0] = tx_packet_count;
4193 test_ch->buf[(size/4)-1] = tx_packet_count;
4194
4195 ret = sdio_write(test_ch->ch, test_ch->buf, size);
4196 if (ret) {
4197 pr_info(TEST_MODULE_NAME ":sdio_write err=%d"
4198 " for chan %s\n",
4199 -ret, test_ch->name);
4200 goto exit_err;
4201 }
4202 tx_packet_count++;
4203 test_ch->tx_bytes += size;
4204 }
4205
4206 read_avail = sdio_read_avail(test_ch->ch);
4207 TEST_DBG(TEST_MODULE_NAME ":channel %s, read_avail=%d\n",
4208 test_ch->name, read_avail);
4209 if (read_avail > 0) {
4210 size = min(packet_size, read_avail);
4211 pr_debug(TEST_MODULE_NAME ":rx size = %d.\n", size);
4212 ret = sdio_read(test_ch->ch, test_ch->buf, size);
4213 if (ret) {
4214 pr_info(TEST_MODULE_NAME ": sdio_read size %d "
4215 " err=%d"
4216 " for chan %s\n",
4217 size, -ret, test_ch->name);
4218 goto exit_err;
4219 }
4220 rx_packet_count++;
4221 test_ch->rx_bytes += size;
4222 }
4223
4224 TEST_DBG(TEST_MODULE_NAME
4225 ":total rx bytes = %d , rx_packet#=%d"
4226 " for chan %s\n",
4227 test_ch->rx_bytes, rx_packet_count, test_ch->name);
4228 TEST_DBG(TEST_MODULE_NAME
4229 ":total tx bytes = %d , tx_packet#=%d"
4230 " for chan %s\n",
4231 test_ch->tx_bytes, tx_packet_count, test_ch->name);
4232
4233 } /* while (tx_packet_count < max_packets ) */
4234
4235 end_jiffy = get_jiffies_64(); /* read the current time */
4236
4237 delta_jiffies = end_jiffy - start_jiffy;
4238 time_msec = jiffies_to_msecs(delta_jiffies);
4239
4240 pr_info(TEST_MODULE_NAME ":total rx bytes = 0x%x , rx_packet#=%d for"
4241 " chan %s.\n",
4242 test_ch->rx_bytes, rx_packet_count, test_ch->name);
4243 pr_info(TEST_MODULE_NAME ":total tx bytes = 0x%x , tx_packet#=%d"
4244 " for chan %s.\n",
4245 test_ch->tx_bytes, tx_packet_count, test_ch->name);
4246
4247 total_bytes = (test_ch->tx_bytes + test_ch->rx_bytes);
4248 pr_err(TEST_MODULE_NAME ":total bytes = %d, time msec = %d"
4249 " for chan %s\n",
4250 total_bytes , (int) time_msec, test_ch->name);
4251
4252 if (!test_ch->random_packet_size) {
Maya Erez241eb922011-10-23 10:51:26 +02004253 if (time_msec) {
4254 throughput = (total_bytes / time_msec) * 8 / 1000;
4255 pr_err(TEST_MODULE_NAME ": %s - Performance = "
4256 "%d Mbit/sec for chan %s\n",
4257 __func__, throughput, test_ch->name);
4258 } else {
4259 pr_err(TEST_MODULE_NAME ": %s - time_msec = 0 Couldn't "
4260 "calculate performence for chan %s\n",
4261 __func__, test_ch->name);
4262 }
4263
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004264 }
4265
4266#ifdef CONFIG_DEBUG_FS
4267 switch (test_ch->ch_id) {
4268 case SDIO_DUN:
4269 test_ctx->debug.dun_throughput = throughput;
4270 break;
4271 case SDIO_RMNT:
4272 test_ctx->debug.rmnt_throughput = throughput;
4273 break;
4274 default:
4275 pr_err(TEST_MODULE_NAME "No debugfs for this channel "
4276 "throughput");
4277 }
4278#endif
4279
4280 pr_err(TEST_MODULE_NAME ": A2 PERFORMANCE TEST END for chan %s.\n",
4281 test_ch->name);
4282
4283 pr_err(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
4284 test_ch->test_completed = 1;
4285 test_ch->test_result = TEST_PASSED;
4286 check_test_completion();
4287 return;
4288
4289exit_err:
4290 pr_err(TEST_MODULE_NAME ": TEST FAIL for chan %s\n", test_ch->name);
4291 test_ch->test_completed = 1;
4292 test_ch->test_result = TEST_FAILED;
4293 check_test_completion();
4294 return;
4295}
4296
4297/**
Maya Erez53508c12011-08-01 14:04:03 +03004298 * rx_cleanup
4299 * This function reads all the messages sent by the modem until
4300 * the read_avail is 0 after 1 second of sleep.
4301 * The function returns the number of packets that was received.
4302 */
4303static void rx_cleanup(struct test_channel *test_ch, int *rx_packet_count)
4304{
4305 int read_avail = 0;
4306 int ret = 0;
Maya Ereze05fc4d2011-09-11 14:18:43 +03004307 int counter = 0;
4308
4309 if (!test_ch || !test_ch->ch) {
4310 pr_err(TEST_MODULE_NAME ":%s NULL channel\n",
4311 __func__);
4312 return;
4313 }
Maya Erez53508c12011-08-01 14:04:03 +03004314
4315 read_avail = sdio_read_avail(test_ch->ch);
4316 TEST_DBG(TEST_MODULE_NAME ":channel %s, read_avail=%d\n",
4317 test_ch->name, read_avail);
4318
4319 /* If no pending messages, wait to see if the modem sends data */
4320 if (read_avail == 0) {
4321 msleep(1000);
4322 read_avail = sdio_read_avail(test_ch->ch);
4323 }
4324
Maya Ereze05fc4d2011-09-11 14:18:43 +03004325 while ((read_avail > 0) && (counter < 10)) {
Maya Erez53508c12011-08-01 14:04:03 +03004326 TEST_DBG(TEST_MODULE_NAME ": read_avail=%d for ch %s\n",
4327 read_avail, test_ch->name);
4328
4329 ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
4330 if (ret) {
4331 pr_info(TEST_MODULE_NAME ": sdio_read size %d "
4332 " err=%d for chan %s\n",
4333 read_avail, -ret, test_ch->name);
4334 break;
4335 }
4336 (*rx_packet_count)++;
4337 test_ch->rx_bytes += read_avail;
4338 read_avail = sdio_read_avail(test_ch->ch);
4339 if (read_avail == 0) {
4340 msleep(1000);
Maya Ereze05fc4d2011-09-11 14:18:43 +03004341 counter++;
Maya Erez53508c12011-08-01 14:04:03 +03004342 read_avail = sdio_read_avail(test_ch->ch);
4343 }
4344 }
4345 pr_info(TEST_MODULE_NAME ": finished cleanup for ch %s, "
4346 "rx_packet_count=%d, total rx bytes=%d\n",
4347 test_ch->name, *rx_packet_count, test_ch->rx_bytes);
4348}
4349
4350
4351/**
4352 * A2 RTT Test
4353 * This function sends a packet and calculate the RTT time of
4354 * this packet.
4355 * The test also calculte Min, Max and Average RTT
4356 */
4357static void a2_rtt_test(struct test_channel *test_ch)
4358{
4359 int ret = 0 ;
4360 u32 read_avail = 0;
4361 u32 write_avail = 0;
4362 int tx_packet_count = 0;
4363 int rx_packet_count = 0;
Maya Erez241eb922011-10-23 10:51:26 +02004364 u16 *buf16 = NULL;
Maya Erez53508c12011-08-01 14:04:03 +03004365 int i;
Maya Erez241eb922011-10-23 10:51:26 +02004366 int max_packets = 0;
4367 u32 packet_size = 0;
Maya Erez53508c12011-08-01 14:04:03 +03004368 s64 start_time, end_time;
4369 int delta_usec = 0;
4370 int time_average = 0;
4371 int min_delta_usec = 0xFFFF;
4372 int max_delta_usec = 0;
4373 int total_time = 0;
4374 int expected_read_size = 0;
Maya Erez241eb922011-10-23 10:51:26 +02004375 int delay_ms = 0;
4376 int slow_rtt_counter = 0;
4377 int read_avail_so_far = 0;
4378
4379 if (test_ch) {
4380 /*
4381 * Cleanup the pending RX data (such as loopback of the
4382 * config msg)
4383 */
4384 rx_cleanup(test_ch, &rx_packet_count);
4385 rx_packet_count = 0;
4386 } else {
4387 return;
4388 }
4389
4390 max_packets = test_ch->config_msg.num_packets;
4391 packet_size = test_ch->packet_length;
4392 buf16 = (u16 *) test_ch->buf;
Maya Erez53508c12011-08-01 14:04:03 +03004393
4394 for (i = 0; i < packet_size / 2; i++)
4395 buf16[i] = (u16) (i & 0xFFFF);
4396
4397 pr_info(TEST_MODULE_NAME ": A2 RTT TEST START for chan %s\n",
4398 test_ch->name);
4399
Maya Erez241eb922011-10-23 10:51:26 +02004400 switch (test_ch->ch_id) {
4401 case SDIO_RMNT:
4402 delay_ms = 100;
4403 break;
4404 case SDIO_CSVT:
4405 delay_ms = 0;
4406 break;
4407 default:
4408 pr_err(TEST_MODULE_NAME ": %s - ch_id invalid.\n",
4409 __func__);
4410 return;
4411 }
Maya Erez53508c12011-08-01 14:04:03 +03004412
4413 while (tx_packet_count < max_packets) {
4414 if (test_ctx->exit_flag) {
4415 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
4416 return;
4417 }
4418 start_time = 0;
4419 end_time = 0;
Maya Erez241eb922011-10-23 10:51:26 +02004420 read_avail_so_far = 0;
Maya Erez53508c12011-08-01 14:04:03 +03004421
Maya Erez241eb922011-10-23 10:51:26 +02004422 if (delay_ms)
4423 msleep(delay_ms);
Maya Erez53508c12011-08-01 14:04:03 +03004424
4425 /* wait for data ready event */
4426 write_avail = sdio_write_avail(test_ch->ch);
4427 TEST_DBG(TEST_MODULE_NAME ":ch %s: write_avail=%d\n",
4428 test_ch->name, write_avail);
4429 if (write_avail == 0) {
4430 wait_event(test_ch->wait_q,
4431 atomic_read(&test_ch->tx_notify_count));
4432 atomic_dec(&test_ch->tx_notify_count);
4433 }
4434
4435 write_avail = sdio_write_avail(test_ch->ch);
4436 TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d\n",
4437 test_ch->name, write_avail);
4438 if (write_avail > 0) {
4439 TEST_DBG(TEST_MODULE_NAME ":tx size = %d for chan %s\n",
4440 packet_size, test_ch->name);
4441 test_ch->buf[0] = tx_packet_count;
4442
4443 start_time = ktime_to_us(ktime_get());
4444 ret = sdio_write(test_ch->ch, test_ch->buf,
4445 packet_size);
4446 if (ret) {
4447 pr_err(TEST_MODULE_NAME ":sdio_write err=%d"
4448 " for chan %s\n",
4449 -ret, test_ch->name);
4450 goto exit_err;
4451 }
4452 tx_packet_count++;
4453 test_ch->tx_bytes += packet_size;
4454 } else {
4455 pr_err(TEST_MODULE_NAME ": Invalid write_avail"
4456 " %d for chan %s\n",
4457 write_avail, test_ch->name);
4458 goto exit_err;
4459 }
4460
4461 expected_read_size = packet_size + A2_HEADER_OVERHEAD;
4462
Maya Erez241eb922011-10-23 10:51:26 +02004463 while (read_avail_so_far < expected_read_size) {
Maya Erez53508c12011-08-01 14:04:03 +03004464
Maya Erez241eb922011-10-23 10:51:26 +02004465 read_avail = sdio_read_avail(test_ch->ch);
4466
4467 if (!read_avail) {
4468 wait_event(test_ch->wait_q,
4469 atomic_read(&test_ch->
4470 rx_notify_count));
4471
4472 atomic_dec(&test_ch->rx_notify_count);
4473 continue;
4474 }
4475
4476 read_avail_so_far += read_avail;
4477
4478 if (read_avail_so_far > expected_read_size) {
4479 pr_err(TEST_MODULE_NAME ": %s - Invalid "
4480 "read_avail(%d) read_avail_so_far(%d) "
4481 "can't be larger than "
4482 "expected_read_size(%d).",
4483 __func__,
4484 read_avail,
4485 read_avail_so_far,
4486 expected_read_size);
4487 goto exit_err;
4488 }
4489
4490 /*
4491 * must read entire pending bytes, so later, we will
4492 * get a notification when more data arrives
4493 */
Maya Erez53508c12011-08-01 14:04:03 +03004494 ret = sdio_read(test_ch->ch, test_ch->buf,
Maya Erez241eb922011-10-23 10:51:26 +02004495 read_avail);
4496
Maya Erez53508c12011-08-01 14:04:03 +03004497 if (ret) {
4498 pr_info(TEST_MODULE_NAME ": sdio_read size %d "
4499 " err=%d for chan %s\n",
Maya Erez241eb922011-10-23 10:51:26 +02004500 read_avail, -ret,
Maya Erez53508c12011-08-01 14:04:03 +03004501 test_ch->name);
4502 goto exit_err;
4503 }
Maya Erez53508c12011-08-01 14:04:03 +03004504 }
4505
Maya Erez241eb922011-10-23 10:51:26 +02004506 end_time = ktime_to_us(ktime_get());
4507 rx_packet_count++;
4508 test_ch->rx_bytes += expected_read_size;
4509
Maya Erez53508c12011-08-01 14:04:03 +03004510 delta_usec = (int)(end_time - start_time);
4511 total_time += delta_usec;
4512 if (delta_usec < min_delta_usec)
4513 min_delta_usec = delta_usec;
4514 if (delta_usec > max_delta_usec)
4515 max_delta_usec = delta_usec;
4516
Maya Erez241eb922011-10-23 10:51:26 +02004517 /* checking the RTT per channel criteria */
4518 if (delta_usec > MAX_AVG_RTT_TIME_USEC) {
4519 pr_err(TEST_MODULE_NAME ": %s - "
4520 "msg # %d - rtt time (%d usec) is "
4521 "longer than %d usec\n",
4522 __func__,
4523 tx_packet_count,
4524 delta_usec,
4525 MAX_AVG_RTT_TIME_USEC);
4526 slow_rtt_counter++;
4527 }
4528
Maya Erez53508c12011-08-01 14:04:03 +03004529 TEST_DBG(TEST_MODULE_NAME
4530 ":RTT time=%d for packet #%d for chan %s\n",
4531 delta_usec, tx_packet_count, test_ch->name);
Maya Erez53508c12011-08-01 14:04:03 +03004532 } /* while (tx_packet_count < max_packets ) */
4533
Maya Erez241eb922011-10-23 10:51:26 +02004534 pr_info(TEST_MODULE_NAME ": %s - tx_packet_count = %d\n",
4535 __func__, tx_packet_count);
Maya Erez53508c12011-08-01 14:04:03 +03004536
Maya Erez241eb922011-10-23 10:51:26 +02004537 pr_info(TEST_MODULE_NAME ": %s - total rx bytes = 0x%x, "
4538 "rx_packet# = %d for chan %s.\n",
4539 __func__, test_ch->rx_bytes, rx_packet_count, test_ch->name);
Maya Erez53508c12011-08-01 14:04:03 +03004540
Maya Erez241eb922011-10-23 10:51:26 +02004541 pr_info(TEST_MODULE_NAME ": %s - total tx bytes = 0x%x, "
4542 "tx_packet# = %d for chan %s.\n",
4543 __func__, test_ch->tx_bytes, tx_packet_count, test_ch->name);
Maya Erez53508c12011-08-01 14:04:03 +03004544
Maya Erez241eb922011-10-23 10:51:26 +02004545 pr_info(TEST_MODULE_NAME ": %s - slow_rtt_counter = %d for "
4546 "chan %s.\n",
4547 __func__, slow_rtt_counter, test_ch->name);
4548
4549 if (tx_packet_count) {
4550 time_average = total_time / tx_packet_count;
4551 pr_info(TEST_MODULE_NAME ":Average RTT time = %d for chan %s\n",
Maya Erez53508c12011-08-01 14:04:03 +03004552 time_average, test_ch->name);
Maya Erez241eb922011-10-23 10:51:26 +02004553 } else {
4554 pr_err(TEST_MODULE_NAME ": %s - tx_packet_count=0. couldn't "
4555 "calculate average rtt time", __func__);
4556 }
4557
Maya Erez53508c12011-08-01 14:04:03 +03004558 pr_info(TEST_MODULE_NAME ":MIN RTT time = %d for chan %s\n",
4559 min_delta_usec, test_ch->name);
4560 pr_info(TEST_MODULE_NAME ":MAX RTT time = %d for chan %s\n",
4561 max_delta_usec, test_ch->name);
4562
4563 pr_info(TEST_MODULE_NAME ": A2 RTT TEST END for chan %s.\n",
4564 test_ch->name);
4565
Maya Erez241eb922011-10-23 10:51:26 +02004566 if (ret)
4567 goto exit_err;
4568
4569 if (time_average == 0 || time_average > MAX_AVG_RTT_TIME_USEC) {
4570 pr_err(TEST_MODULE_NAME ": %s - average_time = %d. Invalid "
4571 "value",
4572 __func__, time_average);
4573 goto exit_err;
4574
4575 }
4576
Maya Erez53508c12011-08-01 14:04:03 +03004577 pr_info(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
4578 test_ch->test_completed = 1;
4579 test_ch->test_result = TEST_PASSED;
4580 check_test_completion();
4581 return;
4582
4583exit_err:
4584 pr_err(TEST_MODULE_NAME ": TEST FAIL for chan %s\n", test_ch->name);
4585 test_ch->test_completed = 1;
4586 test_ch->test_result = TEST_FAILED;
4587 check_test_completion();
4588 return;
4589}
4590
Maya Erez53508c12011-08-01 14:04:03 +03004591/**
Venkat Gopalakrishnandcc6aac2011-08-29 18:57:11 -07004592 * Process Rx Data - Helper for A2 Validation Test
4593 * @test_ch(in/out) : Test channel that contains Rx data buffer to process.
4594 *
4595 * @rx_unprocessed_bytes(in) : Number of bytes to process in the buffer.
4596 *
4597 * @rx_process_packet_state(in/out) :
4598 * Current processing state (used to identify what to process
4599 * next in a partial packet)
4600 *
4601 * @rx_packet_size(in/out) :
4602 * Number of bytes remaining in the packet to be processed.
4603 *
4604 * @rx_packet_count(in/out) :
4605 * Number of packets processed.
4606 */
4607static int process_rx_data(struct test_channel *test_ch,
4608 u32 rx_unprocessed_bytes,
4609 int *rx_process_packet_state,
4610 u16 *rx_packet_size,
4611 int *rx_packet_count)
4612{
4613 u8 *buf = (u8 *)test_ch->buf;
4614 int eop = 0;
4615 int i = 0;
4616 int ret = 0;
4617 u32 *ptr = 0;
4618 u16 size = 0;
4619
4620 /* process rx data */
4621 while (rx_unprocessed_bytes) {
4622 TEST_DBG(TEST_MODULE_NAME ": unprocessed bytes : %u\n",
4623 rx_unprocessed_bytes);
4624
4625 switch (*rx_process_packet_state) {
4626 case RX_PROCESS_PACKET_INIT:
4627 /* process the A2 header */
4628 TEST_DBG(TEST_MODULE_NAME ": "
4629 "RX_PROCESS_PACKET_INIT\n");
4630 *rx_process_packet_state = RX_PROCESS_PACKET_INIT;
4631 if (rx_unprocessed_bytes < 4)
4632 break;
4633
4634 i += 4;
4635 rx_unprocessed_bytes -= 4;
4636
4637 case RX_PROCESS_A2_HEADER:
4638 /* process the rest of A2 header */
4639 TEST_DBG(TEST_MODULE_NAME ": RX_PROCESS_A2_HEADER\n");
4640 *rx_process_packet_state = RX_PROCESS_A2_HEADER;
4641 if (rx_unprocessed_bytes < 4)
4642 break;
4643
4644 ptr = (u32 *)&buf[i];
4645 /*
4646 * upper 2 bytes of the last 4 bytes of A2 header
4647 * contains the size of the packet
4648 */
4649 *rx_packet_size = *ptr >> 0x10;
4650
4651 i += 4;
4652 rx_unprocessed_bytes -= 4;
4653
4654 case RX_PROCESS_PACKET_DATA:
4655 /* process the2_2_ packet data */
4656 TEST_DBG(TEST_MODULE_NAME ": RX_PROCESS_PACKET_DATA "
4657 "- packet size - %u\n", *rx_packet_size);
4658 *rx_process_packet_state = RX_PROCESS_PACKET_DATA;
4659
4660 size = *rx_packet_size;
4661 if (*rx_packet_size <= rx_unprocessed_bytes) {
4662 eop = *rx_packet_size;
4663 *rx_packet_size = 0;
4664 } else {
4665 eop = rx_unprocessed_bytes;
4666 *rx_packet_size = *rx_packet_size -
4667 rx_unprocessed_bytes;
4668 }
4669
4670 /* no more bytes available to process */
4671 if (!eop)
4672 break;
4673 /*
4674 * end of packet is starting from
4675 * the current position
4676 */
4677 eop = eop + i;
4678 TEST_DBG(TEST_MODULE_NAME ": size - %u, "
4679 "packet size - %u eop - %d\n",
4680 size, *rx_packet_size, eop);
4681
4682 /* validate the data */
4683 for (; i < eop; i++) {
4684 if (buf[i] != (test_ch->rx_bytes % 256)) {
4685 pr_err(TEST_MODULE_NAME ": "
4686 "Corrupt data. buf:%u, "
4687 "data:%u\n", buf[i],
4688 test_ch->rx_bytes % 256);
4689 ret = -EINVAL;
4690 goto err;
4691 }
4692 rx_unprocessed_bytes--;
4693 test_ch->rx_bytes++;
4694 }
4695
4696 /* have more data to be processed */
4697 if (*rx_packet_size)
4698 break;
4699
4700 /*
4701 * A2 sends data in 4 byte alignment,
4702 * skip the padding
4703 */
4704 if (size % 4) {
4705 i += 4 - (size % 4);
4706 rx_unprocessed_bytes -= 4 - (size % 4);
4707 }
4708 *rx_packet_count = *rx_packet_count + 1;
4709
4710 /* re init the state to process new packet */
4711 *rx_process_packet_state = RX_PROCESS_PACKET_INIT;
4712 break;
4713 default:
4714 pr_err(TEST_MODULE_NAME ": Invalid case: %d\n",
4715 *rx_process_packet_state);
4716 ret = -EINVAL;
4717 goto err;
4718 }
4719 TEST_DBG(TEST_MODULE_NAME ": Continue processing "
4720 "if more data is available\n");
4721 }
4722
4723err:
4724 return ret;
4725}
4726
4727/**
4728 * A2 Validation Test
4729 * Send packets and validate the returned packets.
4730 * Transmit one packet at a time, while process multiple rx
4731 * packets in a single transaction.
4732 * A transaction is of size min(random number, write_avail).
4733 * A packet consists of a min of 1 byte to channel supported max.
4734 */
4735static void a2_validation_test(struct test_channel *test_ch)
4736{
4737 int ret = 0 ;
4738 u32 read_avail = 0;
4739 u32 write_avail = 0;
4740 int tx_packet_count = 0;
4741 int rx_packet_count = 0;
4742 int initial_rx_packet_count = 0;
4743 u32 size = 0;
4744 u8 *buf8 = (u8 *)test_ch->buf;
4745 int i = 0;
4746 int max_packets = test_ch->config_msg.num_packets;
4747 u16 tx_packet_size = 0;
4748 u16 rx_packet_size = 0;
4749 u32 random_num = 0;
4750 int rx_process_packet_state = RX_PROCESS_PACKET_INIT;
4751
4752 pr_info(TEST_MODULE_NAME ": A2 VALIDATION TEST START for chan %s\n",
4753 test_ch->name);
4754
4755 /* Wait for the initial rx messages before starting the test. */
4756 rx_cleanup(test_ch, &initial_rx_packet_count);
4757
4758 test_ch->tx_bytes = 0;
4759 test_ch->rx_bytes = 0;
4760
4761 /* Continue till we have transmitted and received all packets */
4762 while ((tx_packet_count < max_packets) ||
4763 (rx_packet_count < max_packets)) {
4764
4765 if (test_ctx->exit_flag) {
4766 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
4767 return;
4768 }
4769
4770 random_num = get_random_int();
4771 size = (random_num % test_ch->packet_length) + 1;
4772 TEST_DBG(TEST_MODULE_NAME ": Random tx packet size =%u", size);
4773
4774 /*
4775 * wait for data ready event
4776 * use a func to avoid compiler optimizations
4777 */
4778 write_avail = sdio_write_avail(test_ch->ch);
4779 read_avail = sdio_read_avail(test_ch->ch);
4780 TEST_DBG(TEST_MODULE_NAME ": write_avail=%d, "
4781 "read_avail=%d for chan %s\n",
4782 write_avail, read_avail, test_ch->name);
4783
4784 if ((write_avail == 0) && (read_avail == 0)) {
4785 wait_event(test_ch->wait_q,
4786 atomic_read(&test_ch->any_notify_count));
4787 atomic_set(&test_ch->any_notify_count, 0);
4788 }
4789
4790 /* Transmit data */
4791 write_avail = sdio_write_avail(test_ch->ch);
4792 if ((tx_packet_count < max_packets) && (write_avail > 0)) {
4793 tx_packet_size = min(size, write_avail) ;
4794 TEST_DBG(TEST_MODULE_NAME ": tx size = %u, "
4795 "write_avail = %u tx_packet# = %d\n",
4796 tx_packet_size, write_avail,
4797 tx_packet_count);
4798 memset(test_ch->buf, 0, test_ch->buf_size);
4799 /* populate the buffer */
4800 for (i = 0; i < tx_packet_size; i++) {
4801 buf8[i] = test_ch->tx_bytes % 256;
4802 test_ch->tx_bytes++;
4803 }
4804
4805 ret = sdio_write(test_ch->ch, test_ch->buf,
4806 tx_packet_size);
4807 if (ret) {
4808 pr_err(TEST_MODULE_NAME ":sdio_write err=%d"
4809 " for chan %s\n",
4810 -ret, test_ch->name);
4811 goto exit_err;
4812 }
4813 tx_packet_count++;
4814 }
4815
4816 /* Receive data */
4817 read_avail = sdio_read_avail(test_ch->ch);
4818 if (read_avail > 0) {
4819 TEST_DBG(TEST_MODULE_NAME ": rx size = %u, "
4820 "rx_packet#=%d.\n",
4821 read_avail, rx_packet_count);
4822 memset(test_ch->buf, 0, test_ch->buf_size);
4823
4824 ret = sdio_read(test_ch->ch, test_ch->buf,
4825 read_avail);
4826 if (ret) {
4827 pr_err(TEST_MODULE_NAME ": sdio_read "
4828 "size %d err=%d for chan %s\n",
4829 size, -ret, test_ch->name);
4830 goto exit_err;
4831 }
4832
4833 /* Process data */
4834 ret = process_rx_data(test_ch, read_avail,
4835 &rx_process_packet_state,
4836 &rx_packet_size,
4837 &rx_packet_count);
4838
4839 if (ret != 0)
4840 goto exit_err;
4841 }
4842 TEST_DBG(TEST_MODULE_NAME ": Continue loop ...\n");
4843 }
4844
4845 if (test_ch->tx_bytes != test_ch->rx_bytes) {
4846 pr_err(TEST_MODULE_NAME ": Total number of bytes "
4847 "transmitted (%u) does not match the total "
4848 "number of bytes received (%u).", test_ch->tx_bytes,
4849 test_ch->rx_bytes);
4850 goto exit_err;
4851 }
4852
4853 pr_info(TEST_MODULE_NAME ": A2 VALIDATION TEST END for chan %s.\n",
4854 test_ch->name);
4855
4856 pr_info(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
4857 test_ch->test_completed = 1;
4858 test_ch->test_result = TEST_PASSED;
4859 check_test_completion();
4860 return;
4861
4862exit_err:
4863 pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s\n", test_ch->name);
4864 test_ch->test_completed = 1;
4865 test_ch->test_result = TEST_FAILED;
4866 check_test_completion();
4867 return;
4868}
4869
4870/**
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004871 * sender No loopback Test
4872 */
4873static void sender_no_loopback_test(struct test_channel *test_ch)
4874{
4875 int ret = 0 ;
4876 u32 write_avail = 0;
4877 int packet_count = 0;
4878 int size = 512;
4879 u16 *buf16 = (u16 *) test_ch->buf;
4880 int i;
4881 int max_packet_count = 10000;
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03004882 unsigned int random_num = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004883
4884 max_packet_count = test_ch->config_msg.num_packets;
4885
4886 for (i = 0 ; i < size / 2 ; i++)
4887 buf16[i] = (u16) (i & 0xFFFF);
4888
4889 pr_info(TEST_MODULE_NAME
4890 ":SENDER NO LP TEST START for chan %s\n", test_ch->name);
4891
4892 while (packet_count < max_packet_count) {
4893
4894 if (test_ctx->exit_flag) {
4895 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
4896 return;
4897 }
4898
4899 random_num = get_random_int();
4900 size = (random_num % test_ch->packet_length) + 1;
4901
4902 TEST_DBG(TEST_MODULE_NAME ":SENDER WAIT FOR EVENT "
4903 "for chan %s\n",
4904 test_ch->name);
4905
4906 /* wait for data ready event */
4907 write_avail = sdio_write_avail(test_ch->ch);
4908 TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
4909 if (write_avail < size) {
4910 wait_event(test_ch->wait_q,
4911 atomic_read(&test_ch->tx_notify_count));
4912 atomic_dec(&test_ch->tx_notify_count);
4913 }
4914
4915 write_avail = sdio_write_avail(test_ch->ch);
4916 TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
4917 if (write_avail < size) {
4918 pr_info(TEST_MODULE_NAME ":not enough write avail.\n");
4919 continue;
4920 }
4921
4922 test_ch->buf[0] = packet_count;
4923
4924 ret = sdio_write(test_ch->ch, test_ch->buf, size);
4925 if (ret) {
4926 pr_info(TEST_MODULE_NAME ":sender sdio_write err=%d.\n",
4927 -ret);
4928 goto exit_err;
4929 }
4930
4931 test_ch->tx_bytes += size;
4932 packet_count++;
4933
4934 TEST_DBG(TEST_MODULE_NAME
4935 ":sender total tx bytes = 0x%x , packet#=%d, size=%d"
4936 " for chan %s\n",
4937 test_ch->tx_bytes, packet_count, size, test_ch->name);
4938
4939 } /* end of while */
4940
4941 pr_info(TEST_MODULE_NAME
4942 ":SENDER TEST END: total tx bytes = 0x%x, "
4943 " for chan %s\n",
4944 test_ch->tx_bytes, test_ch->name);
4945
Yaniv Gardi3e327762011-07-27 11:11:04 +03004946 test_ch->modem_result_per_chan = wait_for_result_msg(test_ch);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004947
Yaniv Gardi3e327762011-07-27 11:11:04 +03004948 if (test_ch->modem_result_per_chan) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004949 pr_info(TEST_MODULE_NAME ": TEST PASS for chan %s.\n",
4950 test_ch->name);
4951 test_ch->test_result = TEST_PASSED;
4952 } else {
4953 pr_info(TEST_MODULE_NAME ": TEST FAILURE for chan %s.\n",
4954 test_ch->name);
4955 test_ch->test_result = TEST_FAILED;
4956 }
4957 test_ch->test_completed = 1;
4958 check_test_completion();
4959 return;
4960
4961exit_err:
4962 pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
4963 test_ch->name);
4964 test_ch->test_completed = 1;
4965 test_ch->test_result = TEST_FAILED;
4966 check_test_completion();
4967 return;
4968}
4969
Maya Erez8afd564f2011-08-24 15:57:06 +03004970
4971/**
4972 * Modem reset Test
4973 * The test verifies that it finished sending all the packets
4974 * while there might be modem reset in the middle
4975 */
4976static void modem_reset_test(struct test_channel *test_ch)
4977{
4978 int ret = 0 ;
4979 u32 read_avail = 0;
4980 u32 write_avail = 0;
4981 int tx_packet_count = 0;
4982 int rx_packet_count = 0;
4983 int size = 0;
4984 u16 *buf16 = (u16 *) test_ch->buf;
4985 int i;
4986 int max_packets = 10000;
4987 u32 packet_size = test_ch->buf_size;
4988 int is_err = 0;
4989
4990 max_packets = test_ch->config_msg.num_packets;
4991 packet_size = test_ch->packet_length;
4992
4993 for (i = 0; i < packet_size / 2; i++)
4994 buf16[i] = (u16) (i & 0xFFFF);
4995
4996 pr_info(TEST_MODULE_NAME ": Modem Reset TEST START for chan %s\n",
4997 test_ch->name);
4998
4999 while (tx_packet_count < max_packets) {
5000
5001 if (test_ctx->exit_flag) {
5002 pr_info(TEST_MODULE_NAME ":Exit Test.\n");
5003 return;
5004 }
5005
5006 if (test_ch->card_removed) {
5007 pr_info(TEST_MODULE_NAME ": card removal was detected "
5008 "for chan %s, tx_total=0x%x\n",
5009 test_ch->name, test_ch->tx_bytes);
5010 wait_event(test_ch->wait_q,
5011 atomic_read(&test_ch->card_detected_event));
5012 atomic_set(&test_ch->card_detected_event, 0);
5013 pr_info(TEST_MODULE_NAME ": card_detected_event "
5014 "for chan %s\n", test_ch->name);
5015 if (test_ch->card_removed)
5016 continue;
5017 is_err = 0;
5018 /* Need to wait for the modem to be ready */
5019 msleep(5000);
5020 pr_info(TEST_MODULE_NAME ": sending the config message "
5021 "for chan %s\n", test_ch->name);
5022 send_config_msg(test_ch);
5023 }
5024
5025 /* wait for data ready event */
5026 /* use a func to avoid compiler optimizations */
5027 write_avail = sdio_write_avail(test_ch->ch);
5028 read_avail = sdio_read_avail(test_ch->ch);
5029 TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d, "
5030 "read_avail=%d for chan %s\n",
5031 test_ch->name, write_avail, read_avail,
5032 test_ch->name);
5033 if ((write_avail == 0) && (read_avail == 0)) {
5034 wait_event(test_ch->wait_q,
5035 atomic_read(&test_ch->any_notify_count));
5036 atomic_set(&test_ch->any_notify_count, 0);
5037 }
5038 if (atomic_read(&test_ch->card_detected_event)) {
5039 atomic_set(&test_ch->card_detected_event, 0);
5040 pr_info(TEST_MODULE_NAME ": card_detected_event "
5041 "for chan %s, tx_total=0x%x\n",
5042 test_ch->name, test_ch->tx_bytes);
5043 if (test_ch->card_removed)
5044 continue;
5045 /* Need to wait for the modem to be ready */
5046 msleep(5000);
5047 is_err = 0;
5048 pr_info(TEST_MODULE_NAME ": sending the config message "
5049 "for chan %s\n", test_ch->name);
5050 send_config_msg(test_ch);
5051 }
5052
5053 write_avail = sdio_write_avail(test_ch->ch);
5054 TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d\n",
5055 test_ch->name, write_avail);
5056 if (write_avail > 0) {
5057 size = min(packet_size, write_avail) ;
5058 pr_debug(TEST_MODULE_NAME ":tx size = %d for chan %s\n",
5059 size, test_ch->name);
5060 test_ch->buf[0] = tx_packet_count;
5061 test_ch->buf[(size/4)-1] = tx_packet_count;
5062
5063 TEST_DBG(TEST_MODULE_NAME ":channel %s, sdio_write, "
5064 "size=%d\n", test_ch->name, size);
5065 if (is_err) {
5066 msleep(100);
5067 continue;
5068 }
5069 ret = sdio_write(test_ch->ch, test_ch->buf, size);
5070 if (ret) {
5071 pr_info(TEST_MODULE_NAME ":sdio_write err=%d"
5072 " for chan %s\n",
5073 -ret, test_ch->name);
5074 is_err = 1;
5075 msleep(20);
5076 continue;
5077 }
5078 tx_packet_count++;
5079 test_ch->tx_bytes += size;
5080 test_ch->config_msg.num_packets--;
5081 }
5082
5083 read_avail = sdio_read_avail(test_ch->ch);
5084 TEST_DBG(TEST_MODULE_NAME ":channel %s, read_avail=%d\n",
5085 test_ch->name, read_avail);
5086 if (read_avail > 0) {
5087 size = min(packet_size, read_avail);
5088 pr_debug(TEST_MODULE_NAME ":rx size = %d.\n", size);
5089 TEST_DBG(TEST_MODULE_NAME ":channel %s, sdio_read, "
5090 "size=%d\n", test_ch->name, size);
5091 if (is_err) {
5092 msleep(100);
5093 continue;
5094 }
5095 ret = sdio_read(test_ch->ch, test_ch->buf, size);
5096 if (ret) {
5097 pr_info(TEST_MODULE_NAME ": sdio_read size %d "
5098 " err=%d"
5099 " for chan %s\n",
5100 size, -ret, test_ch->name);
5101 is_err = 1;
5102 msleep(20);
5103 continue;
5104 }
5105 rx_packet_count++;
5106 test_ch->rx_bytes += size;
5107 }
5108
5109 TEST_DBG(TEST_MODULE_NAME
5110 ":total rx bytes = %d , rx_packet#=%d"
5111 " for chan %s\n",
5112 test_ch->rx_bytes, rx_packet_count, test_ch->name);
5113 TEST_DBG(TEST_MODULE_NAME
5114 ":total tx bytes = %d , tx_packet#=%d"
5115 " for chan %s\n",
5116 test_ch->tx_bytes, tx_packet_count, test_ch->name);
5117
5118 udelay(500);
5119
5120 } /* while (tx_packet_count < max_packets ) */
5121
Maya Erez8afd564f2011-08-24 15:57:06 +03005122 pr_info(TEST_MODULE_NAME ":total rx bytes = 0x%x , rx_packet#=%d for"
5123 " chan %s.\n",
5124 test_ch->rx_bytes, rx_packet_count, test_ch->name);
5125 pr_info(TEST_MODULE_NAME ":total tx bytes = 0x%x , tx_packet#=%d"
5126 " for chan %s.\n",
5127 test_ch->tx_bytes, tx_packet_count, test_ch->name);
5128
5129 pr_err(TEST_MODULE_NAME ": Modem Reset TEST END for chan %s.\n",
5130 test_ch->name);
5131
5132 pr_err(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
5133 test_ch->test_completed = 1;
5134 test_ch->test_result = TEST_PASSED;
5135 check_test_completion();
5136 return;
5137}
5138
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005139/**
5140 * Worker thread to handle the tests types
5141 */
5142static void worker(struct work_struct *work)
5143{
5144 struct test_channel *test_ch = NULL;
5145 struct test_work *test_work = container_of(work,
5146 struct test_work,
5147 work);
5148 int test_type = 0;
5149
5150 test_ch = test_work->test_ch;
5151
5152 if (test_ch == NULL) {
5153 pr_err(TEST_MODULE_NAME ":NULL test_ch\n");
5154 return;
5155 }
5156
5157 test_type = test_ch->test_type;
5158
5159 switch (test_type) {
5160 case SDIO_TEST_LOOPBACK_HOST:
5161 loopback_test(test_ch);
5162 break;
5163 case SDIO_TEST_LOOPBACK_CLIENT:
5164 sender_test(test_ch);
5165 break;
5166 case SDIO_TEST_PERF:
5167 a2_performance_test(test_ch);
5168 break;
5169 case SDIO_TEST_LPM_CLIENT_WAKER:
5170 lpm_test(test_ch);
5171 break;
5172 case SDIO_TEST_LPM_HOST_WAKER:
5173 lpm_test_host_waker(test_ch);
5174 break;
5175 case SDIO_TEST_HOST_SENDER_NO_LP:
5176 sender_no_loopback_test(test_ch);
5177 break;
5178 case SDIO_TEST_LPM_RANDOM:
5179 lpm_continuous_rand_test(test_ch);
Maya Erezf204e692011-08-12 22:00:13 +03005180 break;
Maya Erez53508c12011-08-01 14:04:03 +03005181 case SDIO_TEST_RTT:
5182 a2_rtt_test(test_ch);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005183 break;
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03005184 case SDIO_TEST_CLOSE_CHANNEL:
Maya Erezefafaa82011-09-21 12:41:28 +03005185 if (test_ch->ch_id != SDIO_SMEM)
5186 open_close_test(test_ch);
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03005187 break;
Maya Erez8afd564f2011-08-24 15:57:06 +03005188 case SDIO_TEST_MODEM_RESET:
5189 modem_reset_test(test_ch);
5190 break;
Venkat Gopalakrishnandcc6aac2011-08-29 18:57:11 -07005191 case SDIO_TEST_A2_VALIDATION:
5192 a2_validation_test(test_ch);
5193 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005194 default:
5195 pr_err(TEST_MODULE_NAME ":Bad Test type = %d.\n",
5196 (int) test_type);
5197 }
5198}
5199
5200
5201/**
5202 * Notification Callback
5203 *
5204 * Notify the worker
5205 *
5206 */
5207static void notify(void *priv, unsigned channel_event)
5208{
5209 struct test_channel *test_ch = (struct test_channel *) priv;
5210
Yaniv Gardi3e327762011-07-27 11:11:04 +03005211 pr_debug(TEST_MODULE_NAME ": %s - notify event=%d.\n",
5212 __func__, channel_event);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005213
5214 if (test_ch->ch == NULL) {
Yaniv Gardi3e327762011-07-27 11:11:04 +03005215 pr_info(TEST_MODULE_NAME ": %s - notify before ch ready.\n",
5216 __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005217 return;
5218 }
5219
5220 switch (channel_event) {
5221 case SDIO_EVENT_DATA_READ_AVAIL:
5222 atomic_inc(&test_ch->rx_notify_count);
5223 atomic_set(&test_ch->any_notify_count, 1);
Yaniv Gardi3e327762011-07-27 11:11:04 +03005224 TEST_DBG(TEST_MODULE_NAME ": %s - SDIO_EVENT_DATA_READ_AVAIL, "
5225 "any_notify_count=%d, rx_notify_count=%d\n",
5226 __func__,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005227 atomic_read(&test_ch->any_notify_count),
5228 atomic_read(&test_ch->rx_notify_count));
Yaniv Gardi3e327762011-07-27 11:11:04 +03005229 /*
5230 * when there is pending data on a channel we would like to
5231 * turn on the bit mask that implies that there is pending
5232 * data for that channel on that deivce
5233 */
5234 if (test_ch->test_device != NULL &&
5235 test_ch->test_type == SDIO_TEST_LPM_RANDOM) {
5236 spin_lock_irqsave(&test_ch->test_device->lpm_array_lock,
5237 test_ch->test_device->
5238 lpm_array_lock_flags);
5239 test_ch->test_device->read_avail_mask |=
5240 test_ch->channel_mask_id;
5241 test_ch->notify_counter_per_chan++;
5242
5243 lpm_test_update_entry(test_ch, LPM_NOTIFY, "NOTIFY", 0);
5244 spin_unlock_irqrestore(&test_ch->test_device->
5245 lpm_array_lock,
5246 test_ch->test_device->
5247 lpm_array_lock_flags);
5248 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005249 break;
5250
5251 case SDIO_EVENT_DATA_WRITE_AVAIL:
5252 atomic_inc(&test_ch->tx_notify_count);
5253 atomic_set(&test_ch->any_notify_count, 1);
Yaniv Gardi3e327762011-07-27 11:11:04 +03005254 TEST_DBG(TEST_MODULE_NAME ": %s - SDIO_EVENT_DATA_WRITE_AVAIL, "
5255 "any_notify_count=%d, tx_notify_count=%d\n",
5256 __func__,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005257 atomic_read(&test_ch->any_notify_count),
5258 atomic_read(&test_ch->tx_notify_count));
5259 break;
5260
5261 default:
5262 BUG();
5263 }
5264 wake_up(&test_ch->wait_q);
5265
5266}
5267
5268#ifdef CONFIG_MSM_SDIO_SMEM
5269static int sdio_smem_test_cb(int event)
5270{
5271 struct test_channel *tch = test_ctx->test_ch_arr[SDIO_SMEM];
Maya Erezefafaa82011-09-21 12:41:28 +03005272 int i;
5273 int *smem_buf = (int *)test_ctx->smem_buf;
5274 uint32_t val = 0;
5275 int ret = 0;
5276
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005277 pr_debug(TEST_MODULE_NAME ":%s: Received event %d\n", __func__, event);
5278
Maya Erezefafaa82011-09-21 12:41:28 +03005279 if (!tch) {
5280 pr_err(TEST_MODULE_NAME ": %s NULL tch\n", __func__);
5281 return -EINVAL;
5282 }
5283
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005284 switch (event) {
5285 case SDIO_SMEM_EVENT_READ_DONE:
5286 tch->rx_bytes += SMEM_MAX_XFER_SIZE;
Maya Erezefafaa82011-09-21 12:41:28 +03005287 for (i = 0; i < SMEM_MAX_XFER_SIZE;) {
5288 val = (int)*smem_buf;
5289 if ((val != test_ctx->smem_counter) && tch->is_used) {
5290 pr_err(TEST_MODULE_NAME ":%s: Invalid value %d "
5291 "expected %d in smem arr",
5292 __func__, val, test_ctx->smem_counter);
5293 pr_err(TEST_MODULE_NAME ":SMEM test FAILED\n");
5294 tch->test_completed = 1;
5295 tch->test_result = TEST_FAILED;
5296 check_test_completion();
5297 ret = -EINVAL;
5298 goto exit;
5299 }
5300 i += 4;
5301 smem_buf++;
5302 test_ctx->smem_counter++;
5303 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005304 if (tch->rx_bytes >= 40000000) {
Maya Erezefafaa82011-09-21 12:41:28 +03005305 if ((!tch->test_completed) && tch->is_used) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005306 pr_info(TEST_MODULE_NAME ":SMEM test PASSED\n");
5307 tch->test_completed = 1;
5308 tch->test_result = TEST_PASSED;
5309 check_test_completion();
5310 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005311 }
5312 break;
5313 case SDIO_SMEM_EVENT_READ_ERR:
Maya Erezefafaa82011-09-21 12:41:28 +03005314 if (tch->is_used) {
5315 pr_err(TEST_MODULE_NAME ":Read overflow, "
5316 "SMEM test FAILED\n");
5317 tch->test_completed = 1;
5318 tch->test_result = TEST_FAILED;
5319 ret = -EIO;
5320 }
5321 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005322 default:
Maya Erezefafaa82011-09-21 12:41:28 +03005323 if (tch->is_used) {
5324 pr_err(TEST_MODULE_NAME ":Unhandled event %d\n", event);
5325 ret = -EINVAL;
5326 }
5327 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005328 }
Maya Erezefafaa82011-09-21 12:41:28 +03005329exit:
5330 return ret;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005331}
5332
Maya Erezefafaa82011-09-21 12:41:28 +03005333static int sdio_smem_open(struct sdio_smem_client *sdio_smem)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005334{
5335 int ret = 0;
5336
Maya Erezefafaa82011-09-21 12:41:28 +03005337 if (!sdio_smem) {
5338 pr_info(TEST_MODULE_NAME "%s: NULL sdio_smem_client\n",
5339 __func__);
5340 return -EINVAL;
5341 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005342
Maya Erezefafaa82011-09-21 12:41:28 +03005343 if (test_ctx->test_ch_arr[SDIO_SMEM]->ch_ready) {
5344 pr_info(TEST_MODULE_NAME "%s: SDIO_SMEM channel is already opened\n",
5345 __func__);
5346 return 0;
5347 }
5348
5349 test_ctx->test_ch_arr[SDIO_SMEM]->ch_ready = 1;
5350 sdio_smem->buf = test_ctx->smem_buf;
5351 sdio_smem->size = SMEM_MAX_XFER_SIZE;
5352 sdio_smem->cb_func = sdio_smem_test_cb;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005353 ret = sdio_smem_register_client();
5354 if (ret)
5355 pr_info(TEST_MODULE_NAME "%s: Error (%d) registering sdio_smem "
5356 "test client\n",
5357 __func__, ret);
Maya Erezefafaa82011-09-21 12:41:28 +03005358
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005359 return ret;
5360}
5361
Maya Erezefafaa82011-09-21 12:41:28 +03005362static int sdio_smem_test_probe(struct platform_device *pdev)
5363{
5364 test_ctx->sdio_smem = container_of(pdev, struct sdio_smem_client,
5365 plat_dev);
5366
5367 return sdio_smem_open(test_ctx->sdio_smem);
5368}
5369
Maya Erez8afd564f2011-08-24 15:57:06 +03005370static struct platform_driver sdio_smem_client_drv = {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005371 .probe = sdio_smem_test_probe,
5372 .driver = {
5373 .name = "SDIO_SMEM_CLIENT",
5374 .owner = THIS_MODULE,
5375 },
5376};
5377#endif
5378
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005379static void sdio_test_lpm_timeout_handler(unsigned long data)
5380{
5381 struct test_channel *tch = (struct test_channel *)data;
5382
5383 pr_info(TEST_MODULE_NAME ": %s - LPM TEST TIMEOUT Expired after "
5384 "%d ms\n", __func__, tch->timeout_ms);
5385 tch->test_completed = 1;
5386 pr_info(TEST_MODULE_NAME ": %s - tch->test_result = TEST_FAILED\n",
5387 __func__);
5388 tch->test_completed = 1;
5389 tch->test_result = TEST_FAILED;
5390 check_test_completion();
5391 return;
5392}
5393
5394static void sdio_test_lpm_timer_handler(unsigned long data)
5395{
5396 struct test_channel *tch = (struct test_channel *)data;
5397
5398 pr_info(TEST_MODULE_NAME ": %s - LPM TEST Timer Expired after "
5399 "%d ms\n", __func__, tch->timer_interval_ms);
5400
5401 if (!tch) {
5402 pr_err(TEST_MODULE_NAME ": %s - LPM TEST FAILED. "
5403 "tch is NULL\n", __func__);
5404 return;
5405 }
5406
5407 if (!tch->ch) {
5408 pr_err(TEST_MODULE_NAME ": %s - LPM TEST FAILED. tch->ch "
5409 "is NULL\n", __func__);
5410 tch->test_result = TEST_FAILED;
5411 return;
5412 }
5413
5414 /* Verfiy that we voted for sleep */
5415 if (tch->is_ok_to_sleep) {
5416 tch->test_result = TEST_PASSED;
5417 pr_info(TEST_MODULE_NAME ": %s - 8K voted for sleep\n",
5418 __func__);
5419 } else {
5420 tch->test_result = TEST_FAILED;
5421 pr_info(TEST_MODULE_NAME ": %s - 8K voted against sleep\n",
5422 __func__);
5423
5424 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03005425
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005426 sdio_al_unregister_lpm_cb(tch->sdio_al_device);
5427
5428 if (tch->test_type == SDIO_TEST_LPM_HOST_WAKER) {
5429 atomic_set(&tch->wakeup_client, 1);
5430 wake_up(&tch->wait_q);
5431 }
5432}
5433
5434int sdio_test_wakeup_callback(void *device_handle, int is_vote_for_sleep)
5435{
5436 int i = 0;
5437
5438 TEST_DBG(TEST_MODULE_NAME ": %s is_vote_for_sleep=%d!!!",
5439 __func__, is_vote_for_sleep);
5440
5441 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
5442 struct test_channel *tch = test_ctx->test_ch_arr[i];
5443
5444 if ((!tch) || (!tch->is_used) || (!tch->ch_ready))
5445 continue;
5446 if (tch->sdio_al_device == device_handle) {
5447 tch->is_ok_to_sleep = is_vote_for_sleep;
5448
Yaniv Gardi3e327762011-07-27 11:11:04 +03005449 if (tch->test_type == SDIO_TEST_LPM_RANDOM) {
5450 spin_lock_irqsave(&tch->test_device->
5451 lpm_array_lock,
5452 tch->test_device->
5453 lpm_array_lock_flags);
Yaniv Gardi3e327762011-07-27 11:11:04 +03005454 if (is_vote_for_sleep == 1)
5455 lpm_test_update_entry(tch,
5456 LPM_SLEEP,
5457 "SLEEP ", 0);
5458 else
5459 lpm_test_update_entry(tch,
5460 LPM_WAKEUP,
5461 "WAKEUP", 0);
5462
5463 spin_unlock_irqrestore(&tch->test_device->
5464 lpm_array_lock,
5465 tch->test_device->
5466 lpm_array_lock_flags);
5467 break;
5468 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005469 }
5470 }
5471
Yaniv Gardi3e327762011-07-27 11:11:04 +03005472 return 0;
5473}
5474
5475static int sdio_test_find_dev(struct test_channel *tch)
5476{
5477 int j;
5478 int null_index = -1;
5479
5480 for (j = 0 ; j < MAX_NUM_OF_SDIO_DEVICES; ++j) {
5481
5482 struct sdio_test_device *test_dev =
5483 &test_ctx->test_dev_arr[j];
5484
5485 if (test_dev->sdio_al_device == NULL) {
5486 if (null_index == -1)
5487 null_index = j;
5488 continue;
5489 }
5490
5491 if (test_dev->sdio_al_device ==
5492 tch->ch->sdio_al_dev) {
5493 test_dev->open_channels_counter_to_recv++;
5494 test_dev->open_channels_counter_to_send++;
5495 tch->test_device = test_dev;
5496 /* setting mask id for pending data for
5497 this channel */
5498 tch->channel_mask_id = test_dev->next_mask_id;
5499 test_dev->next_mask_id *= 2;
5500 pr_info(TEST_MODULE_NAME ": %s - channel %s "
5501 "got read_mask_id = 0x%x. device "
5502 "next_mask_id=0x%x",
5503 __func__, tch->name, tch->channel_mask_id,
5504 test_dev->next_mask_id);
5505 break;
5506 }
5507 }
5508
5509 /*
5510 * happens ones a new device is "discovered" while testing. i.e
5511 * if testing a few channels, a new deivce will be "discovered" once
5512 * the first channel of a device is being tested
5513 */
5514 if (j == MAX_NUM_OF_SDIO_DEVICES) {
5515
5516 struct sdio_test_device *test_dev =
5517 &test_ctx->
5518 test_dev_arr[null_index];
5519 test_dev->sdio_al_device =
5520 tch->ch->sdio_al_dev;
5521
5522 test_ctx->number_of_active_devices++;
5523 test_ctx->max_number_of_devices++;
5524 test_dev->open_channels_counter_to_recv++;
5525 test_dev->open_channels_counter_to_send++;
5526 test_dev->next_avail_entry_in_array = 0;
5527 tch->test_device = test_dev;
5528 tch->test_device->array_size =
5529 LPM_ARRAY_SIZE;
5530 test_dev->modem_result_per_dev = 1;
5531 tch->modem_result_per_chan = 0;
Yaniv Gardidacd7c32011-09-22 16:12:36 +03005532 test_dev->next_avail_entry_in_array = 0;
Yaniv Gardi3e327762011-07-27 11:11:04 +03005533
5534 spin_lock_init(&test_dev->
5535 lpm_array_lock);
Yaniv Gardi3e327762011-07-27 11:11:04 +03005536
5537 if (tch->test_type == SDIO_TEST_LPM_RANDOM) {
Maya Erez8afd564f2011-08-24 15:57:06 +03005538 pr_err(MODULE_NAME ": %s - "
5539 "Allocating Msg Array for "
5540 "Maximum open channels for device (%d) "
5541 "Channels. Array has %d entries",
5542 __func__,
5543 LPM_MAX_OPEN_CHAN_PER_DEV,
5544 test_dev->array_size);
Yaniv Gardi3e327762011-07-27 11:11:04 +03005545
5546 test_dev->lpm_arr =
5547 kzalloc(sizeof(
5548 struct lpm_entry_type) *
5549 tch->
5550 test_device->array_size,
5551 GFP_KERNEL);
5552
5553 if (!test_dev->lpm_arr) {
5554 pr_err(MODULE_NAME ": %s - "
5555 "lpm_arr is NULL",
5556 __func__);
5557 return -ENOMEM;
5558 }
5559 }
5560
5561 /*
5562 * in new device, initialize next_mask_id, and setting
5563 * mask_id to the channel
5564 */
5565 test_dev->next_mask_id = 0x1;
5566 tch->channel_mask_id = test_dev->next_mask_id;
5567 test_dev->next_mask_id *= 2;
5568 pr_info(TEST_MODULE_NAME ": %s - channel %s got "
5569 "read_mask_id = 0x%x. device next_mask_id=0x%x",
5570 __func__,
5571 tch->name,
5572 tch->channel_mask_id,
5573 test_dev->next_mask_id);
5574 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005575
5576 return 0;
5577}
5578
Yaniv Gardi3e327762011-07-27 11:11:04 +03005579static void check_test_result(void)
5580{
5581 int result = 1;
5582 int i = 0;
5583
5584 test_ctx->max_number_of_devices = 0;
5585
5586 pr_info(TEST_MODULE_NAME ": %s - Woke Up\n", __func__);
5587
5588 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
5589 struct test_channel *tch = test_ctx->test_ch_arr[i];
5590
5591 if ((!tch) || (!tch->is_used) || (!tch->ch_ready))
5592 continue;
5593
5594 if (tch->test_type == SDIO_TEST_LPM_RANDOM)
5595 result &= tch->test_device->final_result_per_dev;
5596 else
5597 if (tch->test_result == TEST_FAILED) {
5598 pr_info(TEST_MODULE_NAME ": %s - "
5599 "Test FAILED\n", __func__);
5600 test_ctx->test_result = TEST_FAILED;
5601 pr_err(TEST_MODULE_NAME ": %s - "
5602 "test_result %d",
5603 __func__, test_ctx->test_result);
5604 return;
5605 }
5606 }
5607
5608 if (result == 0) {
5609 pr_info(TEST_MODULE_NAME ": %s - Test FAILED\n", __func__);
5610 test_ctx->test_result = TEST_FAILED;
5611 pr_err(TEST_MODULE_NAME ": %s - "
5612 "test_result %d",
5613 __func__, test_ctx->test_result);
5614 return;
5615 }
5616
5617 pr_info(TEST_MODULE_NAME ": %s - Test PASSED", __func__);
5618 test_ctx->test_result = TEST_PASSED;
5619 pr_err(TEST_MODULE_NAME ": %s - "
5620 "test_result %d",
5621 __func__, test_ctx->test_result);
5622 return;
5623}
5624
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005625/**
5626 * Test Main
5627 */
5628static int test_start(void)
5629{
5630 int ret = -ENOMEM;
5631 int i;
5632
5633 pr_debug(TEST_MODULE_NAME ":Starting Test ....\n");
5634
5635 test_ctx->test_completed = 0;
5636 test_ctx->test_result = TEST_NO_RESULT;
5637 test_ctx->debug.dun_throughput = 0;
5638 test_ctx->debug.rmnt_throughput = 0;
Yaniv Gardi3e327762011-07-27 11:11:04 +03005639 test_ctx->number_of_active_devices = 0;
5640
5641 pr_err(TEST_MODULE_NAME ": %s - test_result %d",
5642 __func__, test_ctx->test_result);
5643
5644 memset(test_ctx->test_dev_arr, 0,
5645 sizeof(struct sdio_test_device)*MAX_NUM_OF_SDIO_DEVICES);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005646
5647 /* Open The Channels */
5648 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
5649 struct test_channel *tch = test_ctx->test_ch_arr[i];
5650
5651 if ((!tch) || (!tch->is_used))
5652 continue;
5653
5654 tch->rx_bytes = 0;
5655 tch->tx_bytes = 0;
5656
5657 atomic_set(&tch->tx_notify_count, 0);
5658 atomic_set(&tch->rx_notify_count, 0);
5659 atomic_set(&tch->any_notify_count, 0);
5660 atomic_set(&tch->wakeup_client, 0);
5661
Yaniv Gardi3e327762011-07-27 11:11:04 +03005662 /* in case there are values left from previous tests */
5663 tch->notify_counter_per_chan = 0;
Yaniv Gardidacd7c32011-09-22 16:12:36 +03005664 tch->next_index_in_sent_msg_per_chan = 0;
Yaniv Gardi3e327762011-07-27 11:11:04 +03005665
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005666 memset(tch->buf, 0x00, tch->buf_size);
5667 tch->test_result = TEST_NO_RESULT;
5668
5669 tch->test_completed = 0;
5670
Maya Erezefafaa82011-09-21 12:41:28 +03005671 ret = open_sdio_ch(tch);
5672 if (ret)
5673 continue;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005674
Yaniv Gardi3e327762011-07-27 11:11:04 +03005675 if (tch->ch_id != SDIO_SMEM) {
5676 ret = sdio_test_find_dev(tch);
5677
5678 if (ret) {
5679 pr_err(TEST_MODULE_NAME ": %s - "
5680 "sdio_test_find_dev() returned with "
5681 "error", __func__);
5682 return -ENODEV;
5683 }
5684
5685 tch->sdio_al_device = tch->ch->sdio_al_dev;
5686 }
5687
5688 if ((tch->test_type == SDIO_TEST_LPM_HOST_WAKER) ||
5689 (tch->test_type == SDIO_TEST_LPM_CLIENT_WAKER) ||
5690 (tch->test_type == SDIO_TEST_LPM_RANDOM))
5691 sdio_al_register_lpm_cb(tch->sdio_al_device,
5692 sdio_test_wakeup_callback);
5693 }
5694
5695 /*
5696 * make some space between opening the channels and sending the
5697 * config messages
5698 */
5699 msleep(100);
5700
5701 /*
5702 * try to delay send_config_msg of all channels to after the point
5703 * when we open them all
5704 */
5705 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
5706 struct test_channel *tch = test_ctx->test_ch_arr[i];
5707
5708 if ((!tch) || (!tch->is_used))
5709 continue;
5710
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005711 if ((tch->ch_ready) && (tch->ch_id != SDIO_SMEM))
5712 send_config_msg(tch);
5713
5714 if ((tch->test_type == SDIO_TEST_LPM_HOST_WAKER) ||
5715 (tch->test_type == SDIO_TEST_LPM_CLIENT_WAKER) ||
5716 (tch->test_type == SDIO_TEST_LPM_RANDOM)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005717 if (tch->timer_interval_ms > 0) {
5718 pr_info(TEST_MODULE_NAME ": %s - init timer, "
Yaniv Gardi3e327762011-07-27 11:11:04 +03005719 "ms=%d\n",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005720 __func__, tch->timer_interval_ms);
5721 init_timer(&tch->timer);
5722 tch->timer.data = (unsigned long)tch;
5723 tch->timer.function =
5724 sdio_test_lpm_timer_handler;
5725 tch->timer.expires = jiffies +
5726 msecs_to_jiffies(tch->timer_interval_ms);
5727 add_timer(&tch->timer);
5728 }
5729 }
5730 }
5731
5732 pr_debug(TEST_MODULE_NAME ":queue_work..\n");
5733 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
5734 struct test_channel *tch = test_ctx->test_ch_arr[i];
5735
Maya Erezefafaa82011-09-21 12:41:28 +03005736 if ((!tch) || (!tch->is_used) || (!tch->ch_ready))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005737 continue;
Yaniv Gardi3e327762011-07-27 11:11:04 +03005738
Maya Erezefafaa82011-09-21 12:41:28 +03005739 if (tch->ch_id == SDIO_SMEM) {
5740#ifdef CONFIG_MSM_SDIO_SMEM
5741 if (tch->test_type == SDIO_TEST_CLOSE_CHANNEL)
5742 open_close_smem_test(tch);
5743#endif
5744 } else {
5745 queue_work(tch->workqueue, &tch->test_work.work);
5746 }
5747
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005748 }
5749
Yaniv Gardi3e327762011-07-27 11:11:04 +03005750 pr_info(TEST_MODULE_NAME ": %s - Waiting for the test completion\n",
5751 __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005752
Yaniv Gardi3e327762011-07-27 11:11:04 +03005753 wait_event(test_ctx->wait_q, test_ctx->test_completed);
5754 check_test_result();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005755
Maya Erez8afd564f2011-08-24 15:57:06 +03005756 /*
5757 * Close the channels and zero the is_used flag so that if the modem
5758 * will be reset after the test completion we won't re-open
5759 * the channels
5760 */
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03005761 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
5762 struct test_channel *tch = test_ctx->test_ch_arr[i];
5763
Maya Erez8afd564f2011-08-24 15:57:06 +03005764 if ((!tch) || (!tch->is_used))
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03005765 continue;
Maya Erezefafaa82011-09-21 12:41:28 +03005766 if (!tch->ch_ready) {
Maya Erez8afd564f2011-08-24 15:57:06 +03005767 tch->is_used = 0;
5768 continue;
5769 }
Maya Erezefafaa82011-09-21 12:41:28 +03005770
5771 close_sdio_ch(tch);
Maya Erez8afd564f2011-08-24 15:57:06 +03005772 tch->is_used = 0;
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03005773 }
Maya Ereze05fc4d2011-09-11 14:18:43 +03005774
5775 if (test_ctx->test_result == TEST_PASSED)
5776 return 0;
5777 else
5778 return -EINVAL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005779}
5780
5781static int set_params_loopback_9k(struct test_channel *tch)
5782{
5783 if (!tch) {
5784 pr_err(TEST_MODULE_NAME ":NULL channel\n");
5785 return -EINVAL;
5786 }
5787 tch->is_used = 1;
5788 tch->test_type = SDIO_TEST_LOOPBACK_CLIENT;
5789 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
5790 tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
5791 tch->config_msg.num_packets = 10000;
5792 tch->config_msg.num_iterations = 1;
5793
5794 tch->packet_length = 512;
5795 if (tch->ch_id == SDIO_RPC)
5796 tch->packet_length = 128;
5797 tch->timer_interval_ms = 0;
5798
5799 return 0;
5800}
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03005801static int set_params_loopback_9k_close(struct test_channel *tch)
5802{
5803 if (!tch) {
5804 pr_err(TEST_MODULE_NAME ":NULL channel\n");
5805 return -EINVAL;
5806 }
5807 tch->is_used = 1;
5808 tch->test_type = SDIO_TEST_CLOSE_CHANNEL;
5809 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
5810 tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
5811 tch->config_msg.num_packets = 5000;
5812 tch->config_msg.num_iterations = 1;
5813 tch->max_burst_size = 10;
5814 switch (tch->ch_id) {
5815 case SDIO_DUN:
5816 case SDIO_RPC:
5817 tch->packet_length = 128; /* max is 2K*/
5818 break;
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03005819 case SDIO_DIAG:
5820 case SDIO_RMNT:
5821 default:
5822 tch->packet_length = 512; /* max is 4k */
5823 }
5824 tch->timer_interval_ms = 0;
5825 return 0;
5826}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005827static int set_params_a2_perf(struct test_channel *tch)
5828{
5829 if (!tch) {
5830 pr_err(TEST_MODULE_NAME ":NULL channel\n");
5831 return -EINVAL;
5832 }
5833 tch->is_used = 1;
5834 tch->test_type = SDIO_TEST_PERF;
5835 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
5836 tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
Maya Erez241eb922011-10-23 10:51:26 +02005837
5838 switch (tch->ch_id) {
5839 case SDIO_DIAG:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005840 tch->packet_length = 512;
Maya Erez241eb922011-10-23 10:51:26 +02005841 break;
5842 case SDIO_DUN:
5843 tch->packet_length = DUN_PACKET_SIZE;
5844 break;
5845 case SDIO_CSVT:
5846 tch->packet_length = CSVT_PACKET_SIZE;
5847 break;
5848 default:
5849 tch->packet_length = MAX_XFER_SIZE;
5850 break;
5851 }
5852
Maya Erezbde9df82011-08-02 14:40:00 +03005853 pr_info(TEST_MODULE_NAME ": %s: packet_length=%d", __func__,
5854 tch->packet_length);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005855
5856 tch->config_msg.num_packets = 10000;
5857 tch->config_msg.num_iterations = 1;
5858 tch->random_packet_size = 0;
5859
5860 tch->timer_interval_ms = 0;
5861
5862 return 0;
5863}
5864
Maya Erez53508c12011-08-01 14:04:03 +03005865static int set_params_rtt(struct test_channel *tch)
5866{
5867 if (!tch) {
5868 pr_err(TEST_MODULE_NAME ":NULL channel\n");
5869 return -EINVAL;
5870 }
5871 tch->is_used = 1;
5872 tch->test_type = SDIO_TEST_RTT;
5873 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
5874 tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
Maya Erez241eb922011-10-23 10:51:26 +02005875
5876 switch (tch->ch_id) {
5877 case SDIO_RMNT:
5878 tch->packet_length = SDIO_RMNT_RTT_PACKET_SIZE;
5879 break;
5880 case SDIO_CSVT:
5881 tch->packet_length = SDIO_CSVT_RTT_PACKET_SIZE;
5882 break;
5883 default:
5884 pr_err(TEST_MODULE_NAME ": %s - ch_id invalid.\n", __func__);
5885 return -EINVAL;
5886 }
5887
5888 pr_info(TEST_MODULE_NAME ": %s: packet_length=%d", __func__,
5889 tch->packet_length);
Maya Erez53508c12011-08-01 14:04:03 +03005890
5891 tch->config_msg.num_packets = 200;
5892 tch->config_msg.num_iterations = 1;
5893 tch->random_packet_size = 0;
5894
5895 tch->timer_interval_ms = 0;
5896
5897 return 0;
5898}
5899
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005900static int set_params_a2_small_pkts(struct test_channel *tch)
5901{
5902 if (!tch) {
5903 pr_err(TEST_MODULE_NAME ":NULL channel\n");
5904 return -EINVAL;
5905 }
5906 tch->is_used = 1;
5907 tch->test_type = SDIO_TEST_PERF;
5908 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
5909 tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
5910 tch->packet_length = 128;
5911
5912 tch->config_msg.num_packets = 1000000;
5913 tch->config_msg.num_iterations = 1;
5914 tch->random_packet_size = 1;
5915
5916 tch->timer_interval_ms = 0;
5917
5918 return 0;
5919}
5920
Maya Erez8afd564f2011-08-24 15:57:06 +03005921static int set_params_modem_reset(struct test_channel *tch)
5922{
5923 if (!tch) {
5924 pr_err(TEST_MODULE_NAME ":NULL channel\n");
5925 return -EINVAL;
5926 }
5927 tch->is_used = 1;
5928 tch->test_type = SDIO_TEST_MODEM_RESET;
5929 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
5930 tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
5931 tch->packet_length = 512;
5932 if (tch->ch_id == SDIO_RPC)
5933 tch->packet_length = 128;
5934 else if ((tch->ch_id == SDIO_RMNT) || (tch->ch_id == SDIO_DUN))
5935 tch->packet_length = MAX_XFER_SIZE;
5936
5937 tch->config_msg.num_packets = 50000;
5938 tch->config_msg.num_iterations = 1;
5939
5940 tch->timer_interval_ms = 0;
5941
5942 return 0;
5943}
5944
Venkat Gopalakrishnandcc6aac2011-08-29 18:57:11 -07005945static int set_params_a2_validation(struct test_channel *tch)
5946{
5947 if (!tch) {
5948 pr_err(TEST_MODULE_NAME ":NULL channel\n");
5949 return -EINVAL;
5950 }
5951 tch->is_used = 1;
5952 tch->test_type = SDIO_TEST_A2_VALIDATION;
5953 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
5954 tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
5955
5956 if (tch->ch_id == SDIO_RMNT)
5957 tch->packet_length = RMNT_PACKET_SIZE;
5958 else if (tch->ch_id == SDIO_DUN)
5959 tch->packet_length = DUN_PACKET_SIZE;
5960 else
5961 tch->packet_length = MAX_XFER_SIZE;
5962
5963 tch->config_msg.num_packets = 10000;
5964 tch->config_msg.num_iterations = 1;
5965 tch->timer_interval_ms = 0;
5966
5967 return 0;
5968}
5969
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005970static int set_params_smem_test(struct test_channel *tch)
5971{
5972 if (!tch) {
5973 pr_err(TEST_MODULE_NAME ":NULL channel\n");
5974 return -EINVAL;
5975 }
5976 tch->is_used = 1;
5977 tch->timer_interval_ms = 0;
5978
5979 return 0;
5980}
5981
5982static int set_params_lpm_test(struct test_channel *tch,
5983 enum sdio_test_case_type test,
5984 int timer_interval_ms)
5985{
5986 static int first_time = 1;
5987 if (!tch) {
5988 pr_err(TEST_MODULE_NAME ": %s - NULL channel\n", __func__);
5989 return -EINVAL;
5990 }
Yaniv Gardi3e327762011-07-27 11:11:04 +03005991
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005992 tch->is_used = 1;
5993 tch->test_type = test;
5994 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
5995 tch->config_msg.test_case = test;
Yaniv Gardi3e327762011-07-27 11:11:04 +03005996 tch->config_msg.num_packets = LPM_TEST_NUM_OF_PACKETS;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005997 tch->config_msg.num_iterations = 1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005998 tch->timer_interval_ms = timer_interval_ms;
5999 tch->timeout_ms = 10000;
6000
6001 tch->packet_length = 0;
6002 if (test != SDIO_TEST_LPM_RANDOM) {
6003 init_timer(&tch->timeout_timer);
6004 tch->timeout_timer.data = (unsigned long)tch;
6005 tch->timeout_timer.function = sdio_test_lpm_timeout_handler;
6006 tch->timeout_timer.expires = jiffies +
6007 msecs_to_jiffies(tch->timeout_ms);
6008 add_timer(&tch->timeout_timer);
6009 pr_info(TEST_MODULE_NAME ": %s - Initiated LPM TIMEOUT TIMER."
6010 "set to %d ms\n",
6011 __func__, tch->timeout_ms);
6012 }
6013
6014 if (first_time) {
6015 pr_info(TEST_MODULE_NAME ": %s - wake_lock_init() called\n",
6016 __func__);
6017 wake_lock_init(&test_ctx->wake_lock,
6018 WAKE_LOCK_SUSPEND, TEST_MODULE_NAME);
6019 first_time = 0;
6020 }
6021
6022 pr_info(TEST_MODULE_NAME ": %s - wake_lock() for the TEST is "
Yaniv Gardi3e327762011-07-27 11:11:04 +03006023 "called channel %s. to prevent real sleeping\n",
6024 __func__, tch->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006025 wake_lock(&test_ctx->wake_lock);
6026
6027 return 0;
6028}
6029
6030static int set_params_8k_sender_no_lp(struct test_channel *tch)
6031{
6032 if (!tch) {
6033 pr_err(TEST_MODULE_NAME ":NULL channel\n");
6034 return -EINVAL;
6035 }
6036 tch->is_used = 1;
6037 tch->test_type = SDIO_TEST_HOST_SENDER_NO_LP;
6038 tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
6039 tch->config_msg.test_case = SDIO_TEST_HOST_SENDER_NO_LP;
6040 tch->config_msg.num_packets = 1000;
6041 tch->config_msg.num_iterations = 1;
6042
6043 tch->packet_length = 512;
6044 if (tch->ch_id == SDIO_RPC)
6045 tch->packet_length = 128;
6046 tch->timer_interval_ms = 0;
6047
6048 return 0;
6049}
6050
Maya Erezf204e692011-08-12 22:00:13 +03006051static void set_pseudo_random_seed(void)
6052{
6053 /* Set the seed accoring to the kernel command parameters if any or
6054 get a random value */
6055 if (seed != 0) {
6056 test_ctx->lpm_pseudo_random_seed = seed;
6057 } else {
6058 test_ctx->lpm_pseudo_random_seed =
6059 (unsigned int)(get_jiffies_64() & 0xFFFF);
6060 test_ctx->lpm_pseudo_random_seed =
6061 pseudo_random_seed(&test_ctx->lpm_pseudo_random_seed);
6062 }
6063
6064 pr_info(TEST_MODULE_NAME ":%s: seed is %u",
6065 __func__, test_ctx->lpm_pseudo_random_seed);
6066}
6067
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03006068/*
6069 for each channel
6070 1. open channel
6071 2. close channel
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03006072*/
Yaniv Gardib4237782011-08-31 20:06:16 +03006073static int close_channel_lpm_test(int channel_num)
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03006074{
6075 int ret = 0;
6076 struct test_channel *tch = NULL;
Yaniv Gardib4237782011-08-31 20:06:16 +03006077 tch = test_ctx->test_ch_arr[channel_num];
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03006078
Maya Erez241eb922011-10-23 10:51:26 +02006079 if (!tch) {
6080 pr_info(TEST_MODULE_NAME ":%s ch#%d is NULL\n",
6081 __func__, channel_num);
6082 return 0;
6083 }
6084
Maya Erezefafaa82011-09-21 12:41:28 +03006085 ret = open_sdio_ch(tch);
6086 if (ret) {
6087 pr_err(TEST_MODULE_NAME":%s open channel %s"
6088 " failed\n", __func__, tch->name);
6089 return ret;
6090 } else {
6091 pr_info(TEST_MODULE_NAME":%s open channel %s"
6092 " success\n", __func__, tch->name);
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03006093 }
Maya Erezefafaa82011-09-21 12:41:28 +03006094 ret = close_sdio_ch(tch);
Yaniv Gardib4237782011-08-31 20:06:16 +03006095 if (ret) {
6096 pr_err(TEST_MODULE_NAME":%s close channel %s"
6097 " failed\n", __func__, tch->name);
6098 return ret;
6099 } else {
6100 pr_info(TEST_MODULE_NAME":%s close channel %s"
6101 " success\n", __func__, tch->name);
Yaniv Gardib4237782011-08-31 20:06:16 +03006102 }
6103
6104 tch->is_used = 0;
6105
Konstantin Dorfman65ac9222011-08-18 16:30:17 +03006106 return ret;
6107}
6108
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006109/**
6110 * Write File.
6111 *
6112 * @note Trigger the test from user space by:
6113 * echo 1 > /dev/sdio_al_test
6114 *
6115 */
6116ssize_t test_write(struct file *filp, const char __user *buf, size_t size,
6117 loff_t *f_pos)
6118{
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03006119 sdio_al_test_initial_dev_and_chan(test_ctx);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006120
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03006121 if (strict_strtol(buf, 10, &test_ctx->testcase))
6122 return -EINVAL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006123
6124 switch (test_ctx->testcase) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006125 case 98:
6126 pr_info(TEST_MODULE_NAME " set runtime debug on");
6127 test_ctx->runtime_debug = 1;
6128 return size;
6129 case 99:
6130 pr_info(TEST_MODULE_NAME " set runtime debug off");
6131 test_ctx->runtime_debug = 0;
6132 return size;
6133 default:
6134 pr_info(TEST_MODULE_NAME ":Bad Test number = %d.\n",
6135 (int)test_ctx->testcase);
Maya Erez8afd564f2011-08-24 15:57:06 +03006136 return size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006137 }
Yaniv Gardi0e8a5ad2011-08-29 10:32:43 +03006138
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006139 return size;
6140}
6141
6142/**
6143 * Test Channel Init.
6144 */
6145int test_channel_init(char *name)
6146{
6147 struct test_channel *test_ch;
6148 int ch_id = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006149 int ret;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006150
6151 pr_debug(TEST_MODULE_NAME ":%s.\n", __func__);
Venkat Gopalakrishnan3ebdd432011-11-08 19:53:43 -08006152 pr_info(TEST_MODULE_NAME ": init test channel %s.\n", name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006153
6154 ch_id = channel_name_to_id(name);
6155 pr_debug(TEST_MODULE_NAME ":id = %d.\n", ch_id);
6156 if (test_ctx->test_ch_arr[ch_id] == NULL) {
6157 test_ch = kzalloc(sizeof(*test_ch), GFP_KERNEL);
6158 if (test_ch == NULL) {
6159 pr_err(TEST_MODULE_NAME ":kzalloc err for allocating "
6160 "test_ch %s.\n",
6161 name);
6162 return -ENOMEM;
6163 }
6164 test_ctx->test_ch_arr[ch_id] = test_ch;
6165
6166 test_ch->ch_id = ch_id;
6167
Maya Erez8afd564f2011-08-24 15:57:06 +03006168 strncpy(test_ch->name, name,
6169 strnlen(name, TEST_CH_NAME_SIZE)-SDIO_TEST_POSTFIX_SIZE);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006170
6171 test_ch->buf_size = MAX_XFER_SIZE;
6172
6173 test_ch->buf = kzalloc(test_ch->buf_size, GFP_KERNEL);
6174 if (test_ch->buf == NULL) {
6175 kfree(test_ch);
6176 test_ctx->test_ch = NULL;
6177 return -ENOMEM;
6178 }
6179
6180 if (test_ch->ch_id == SDIO_SMEM) {
6181 test_ctx->smem_buf = kzalloc(SMEM_MAX_XFER_SIZE,
6182 GFP_KERNEL);
6183 if (test_ctx->smem_buf == NULL) {
6184 pr_err(TEST_MODULE_NAME ":%s: Unable to "
6185 "allocate smem buf\n",
6186 __func__);
6187 kfree(test_ch);
6188 test_ctx->test_ch = NULL;
6189 return -ENOMEM;
6190 }
6191
6192#ifdef CONFIG_MSM_SDIO_SMEM
Maya Erez8afd564f2011-08-24 15:57:06 +03006193 ret = platform_driver_register(&sdio_smem_client_drv);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006194 if (ret) {
6195 pr_err(TEST_MODULE_NAME ":%s: Unable to "
6196 "register sdio smem "
6197 "test client\n",
6198 __func__);
6199 return ret;
6200 }
6201#endif
6202 } else {
6203 test_ch->workqueue =
6204 create_singlethread_workqueue(test_ch->name);
6205 test_ch->test_work.test_ch = test_ch;
6206 INIT_WORK(&test_ch->test_work.work, worker);
6207
6208 init_waitqueue_head(&test_ch->wait_q);
6209 }
6210 } else {
Maya Erez8afd564f2011-08-24 15:57:06 +03006211 test_ch = test_ctx->test_ch_arr[ch_id];
6212 pr_info(TEST_MODULE_NAME ":%s: ch %s was detected again\n",
6213 __func__, test_ch->name);
6214 test_ch->card_removed = 0;
6215 if ((test_ch->is_used) &&
6216 (test_ch->test_type == SDIO_TEST_MODEM_RESET)) {
6217 if (test_ch->ch_id == SDIO_SMEM) {
Maya Erezefafaa82011-09-21 12:41:28 +03006218#ifdef CONFIG_MSM_SDIO_SMEM
6219 ret = add_sdio_smem();
6220 if (ret) {
6221 test_ch->ch_ready = false;
6222 return 0;
6223 }
6224#endif
Maya Erez8afd564f2011-08-24 15:57:06 +03006225 } else {
Maya Erezefafaa82011-09-21 12:41:28 +03006226 ret = open_sdio_ch(test_ch);
Maya Erez8afd564f2011-08-24 15:57:06 +03006227 if (ret) {
6228 pr_info(TEST_MODULE_NAME
Maya Erezefafaa82011-09-21 12:41:28 +03006229 ":%s: open channel %s failed\n",
6230 __func__, test_ch->name);
Maya Erez8afd564f2011-08-24 15:57:06 +03006231 return 0;
6232 }
6233 ret = sdio_test_find_dev(test_ch);
6234
6235 if (ret) {
6236 pr_err(TEST_MODULE_NAME ": %s - "
6237 "sdio_test_find_dev() returned "
6238 "with error", __func__);
6239 return -ENODEV;
6240 }
6241
6242 test_ch->sdio_al_device =
6243 test_ch->ch->sdio_al_dev;
6244 }
6245 atomic_set(&test_ch->card_detected_event, 1);
6246 wake_up(&test_ch->wait_q);
6247 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006248 }
6249
6250 return 0;
6251}
6252
Maya Erez8afd564f2011-08-24 15:57:06 +03006253static int sdio_test_channel_probe(struct platform_device *pdev)
6254{
6255 if (!pdev)
6256 return -EIO;
6257 return test_channel_init((char *)pdev->name);
6258}
6259
6260static int sdio_test_channel_remove(struct platform_device *pdev)
6261{
6262 int ch_id;
6263
6264 if (!pdev)
6265 return -EIO;
6266
6267 ch_id = channel_name_to_id((char *)pdev->name);
6268 if (test_ctx->test_ch_arr[ch_id] == NULL)
6269 return 0;
6270
6271 pr_info(TEST_MODULE_NAME "%s: remove ch %s\n",
6272 __func__, test_ctx->test_ch_arr[ch_id]->name);
Maya Erezefafaa82011-09-21 12:41:28 +03006273
6274 if ((ch_id == SDIO_SMEM) && (test_ctx->smem_pdev)) {
6275 platform_device_unregister(test_ctx->smem_pdev);
6276 test_ctx->smem_pdev = NULL;
6277 }
6278
Maya Erez8afd564f2011-08-24 15:57:06 +03006279 test_ctx->test_ch_arr[ch_id]->ch_ready = 0;
6280 test_ctx->test_ch_arr[ch_id]->card_removed = 1;
6281
6282 return 0;
6283
6284}
6285
Venkat Gopalakrishnan3ebdd432011-11-08 19:53:43 -08006286static int sdio_test_channel_csvt_probe(struct platform_device *pdev)
6287{
6288 int ret = 0;
6289
6290 if (!pdev)
6291 return -ENODEV;
6292
6293 test_ctx->csvt_app_pdev = platform_device_alloc("SDIO_CSVT_TEST_APP",
6294 -1);
6295 ret = platform_device_add(test_ctx->csvt_app_pdev);
6296 if (ret) {
6297 pr_err(MODULE_NAME ":platform_device_add failed, "
6298 "ret=%d\n", ret);
6299 return ret;
6300 }
6301
6302 return sdio_test_channel_probe(pdev);
6303}
6304
6305static int sdio_test_channel_csvt_remove(struct platform_device *pdev)
6306{
6307 if (!pdev)
6308 return -ENODEV;
6309
6310 platform_device_unregister(test_ctx->csvt_app_pdev);
6311
6312 return sdio_test_channel_remove(pdev);
6313}
6314
Maya Erez8afd564f2011-08-24 15:57:06 +03006315static struct platform_driver sdio_rpc_drv = {
6316 .probe = sdio_test_channel_probe,
6317 .remove = sdio_test_channel_remove,
6318 .driver = {
6319 .name = "SDIO_RPC_TEST",
6320 .owner = THIS_MODULE,
6321 },
6322};
6323
6324static struct platform_driver sdio_qmi_drv = {
6325 .probe = sdio_test_channel_probe,
6326 .remove = sdio_test_channel_remove,
6327 .driver = {
6328 .name = "SDIO_QMI_TEST",
6329 .owner = THIS_MODULE,
6330 },
6331};
6332
6333static struct platform_driver sdio_diag_drv = {
6334 .probe = sdio_test_channel_probe,
6335 .remove = sdio_test_channel_remove,
6336 .driver = {
6337 .name = "SDIO_DIAG_TEST",
6338 .owner = THIS_MODULE,
6339 },
6340};
6341
6342static struct platform_driver sdio_smem_drv = {
6343 .probe = sdio_test_channel_probe,
6344 .remove = sdio_test_channel_remove,
6345 .driver = {
6346 .name = "SDIO_SMEM_TEST",
6347 .owner = THIS_MODULE,
6348 },
6349};
6350
6351static struct platform_driver sdio_rmnt_drv = {
6352 .probe = sdio_test_channel_probe,
6353 .remove = sdio_test_channel_remove,
6354 .driver = {
6355 .name = "SDIO_RMNT_TEST",
6356 .owner = THIS_MODULE,
6357 },
6358};
6359
6360static struct platform_driver sdio_dun_drv = {
6361 .probe = sdio_test_channel_probe,
6362 .remove = sdio_test_channel_remove,
6363 .driver = {
6364 .name = "SDIO_DUN_TEST",
6365 .owner = THIS_MODULE,
6366 },
6367};
6368
Maya Erez241eb922011-10-23 10:51:26 +02006369static struct platform_driver sdio_csvt_drv = {
Venkat Gopalakrishnan3ebdd432011-11-08 19:53:43 -08006370 .probe = sdio_test_channel_csvt_probe,
6371 .remove = sdio_test_channel_csvt_remove,
Maya Erez241eb922011-10-23 10:51:26 +02006372 .driver = {
6373 .name = "SDIO_CSVT_TEST",
6374 .owner = THIS_MODULE,
6375 },
6376};
6377
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006378static struct class *test_class;
6379
6380const struct file_operations test_fops = {
6381 .owner = THIS_MODULE,
6382 .write = test_write,
6383};
6384
6385/**
6386 * Module Init.
6387 */
6388static int __init test_init(void)
6389{
6390 int ret;
6391
6392 pr_debug(TEST_MODULE_NAME ":test_init.\n");
6393
Yaniv Gardi3e327762011-07-27 11:11:04 +03006394 test_ctx = kzalloc(sizeof(struct test_context), GFP_KERNEL);
6395
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006396 if (test_ctx == NULL) {
6397 pr_err(TEST_MODULE_NAME ":kzalloc err.\n");
6398 return -ENOMEM;
6399 }
6400 test_ctx->test_ch = NULL;
6401 test_ctx->signature = TEST_SIGNATURE;
6402
6403 test_ctx->name = "UNKNOWN";
6404
6405 init_waitqueue_head(&test_ctx->wait_q);
6406
6407#ifdef CONFIG_DEBUG_FS
6408 sdio_al_test_debugfs_init();
6409#endif
6410
6411 test_class = class_create(THIS_MODULE, TEST_MODULE_NAME);
6412
6413 ret = alloc_chrdev_region(&test_ctx->dev_num, 0, 1, TEST_MODULE_NAME);
6414 if (ret) {
6415 pr_err(TEST_MODULE_NAME "alloc_chrdev_region err.\n");
6416 return -ENODEV;
6417 }
6418
6419 test_ctx->dev = device_create(test_class, NULL, test_ctx->dev_num,
6420 test_ctx, TEST_MODULE_NAME);
6421 if (IS_ERR(test_ctx->dev)) {
6422 pr_err(TEST_MODULE_NAME ":device_create err.\n");
6423 return -ENODEV;
6424 }
6425
6426 test_ctx->cdev = cdev_alloc();
6427 if (test_ctx->cdev == NULL) {
6428 pr_err(TEST_MODULE_NAME ":cdev_alloc err.\n");
6429 return -ENODEV;
6430 }
6431 cdev_init(test_ctx->cdev, &test_fops);
6432 test_ctx->cdev->owner = THIS_MODULE;
6433
6434 ret = cdev_add(test_ctx->cdev, test_ctx->dev_num, 1);
6435 if (ret)
6436 pr_err(TEST_MODULE_NAME ":cdev_add err=%d\n", -ret);
6437 else
6438 pr_debug(TEST_MODULE_NAME ":SDIO-AL-Test init OK..\n");
6439
Maya Erez8afd564f2011-08-24 15:57:06 +03006440 platform_driver_register(&sdio_rpc_drv);
6441 platform_driver_register(&sdio_qmi_drv);
6442 platform_driver_register(&sdio_diag_drv);
6443 platform_driver_register(&sdio_smem_drv);
6444 platform_driver_register(&sdio_rmnt_drv);
6445 platform_driver_register(&sdio_dun_drv);
Maya Erez241eb922011-10-23 10:51:26 +02006446 platform_driver_register(&sdio_csvt_drv);
Maya Erez8afd564f2011-08-24 15:57:06 +03006447
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006448 return ret;
6449}
6450
6451/**
6452 * Module Exit.
6453 */
6454static void __exit test_exit(void)
6455{
6456 int i;
6457
6458 pr_debug(TEST_MODULE_NAME ":test_exit.\n");
6459
6460 test_ctx->exit_flag = true;
6461
6462 msleep(100); /* allow gracefully exit of the worker thread */
6463
6464 cdev_del(test_ctx->cdev);
6465 device_destroy(test_class, test_ctx->dev_num);
6466 unregister_chrdev_region(test_ctx->dev_num, 1);
6467
Maya Erez8afd564f2011-08-24 15:57:06 +03006468 platform_driver_unregister(&sdio_rpc_drv);
6469 platform_driver_unregister(&sdio_qmi_drv);
6470 platform_driver_unregister(&sdio_diag_drv);
6471 platform_driver_unregister(&sdio_smem_drv);
6472 platform_driver_unregister(&sdio_rmnt_drv);
6473 platform_driver_unregister(&sdio_dun_drv);
Maya Erez241eb922011-10-23 10:51:26 +02006474 platform_driver_unregister(&sdio_csvt_drv);
Maya Erez8afd564f2011-08-24 15:57:06 +03006475
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006476 for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
6477 struct test_channel *tch = test_ctx->test_ch_arr[i];
6478 if (!tch)
6479 continue;
6480 kfree(tch->buf);
6481 kfree(tch);
6482 }
6483
6484#ifdef CONFIG_DEBUG_FS
6485 sdio_al_test_debugfs_cleanup();
6486#endif
6487
6488 kfree(test_ctx);
6489
6490 pr_debug(TEST_MODULE_NAME ":test_exit complete.\n");
6491}
6492
6493module_init(test_init);
6494module_exit(test_exit);
6495
6496MODULE_LICENSE("GPL v2");
6497MODULE_DESCRIPTION("SDIO_AL Test");
6498MODULE_AUTHOR("Amir Samuelov <amirs@codeaurora.org>");
6499
6500