usb: gadget: g_ffs: Allow to set bmAttributes of configuration
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / char / ts0710_mux.c
1 /* File: mux_driver.c
2  *
3  * Portions derived from rfcomm.c, original header as follows:
4  *
5  * Copyright (C) 2000, 2001  Axis Communications AB
6  *
7  * Author: Mats Friden <mats.friden@axis.com>
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * Exceptionally, Axis Communications AB grants discretionary and
24  * conditional permissions for additional use of the text contained
25  * in the company's release of the AXIS OpenBT Stack under the
26  * provisions set forth hereunder.
27  *
28  * Provided that, if you use the AXIS OpenBT Stack with other files,
29  * that do not implement functionality as specified in the Bluetooth
30  * System specification, to produce an executable, this does not by
31  * itself cause the resulting executable to be covered by the GNU
32  * General Public License. Your use of that executable is in no way
33  * restricted on account of using the AXIS OpenBT Stack code with it.
34  *
35  * This exception does not however invalidate any other reasons why
36  * the executable file might be covered by the provisions of the GNU
37  * General Public License.
38  *
39  */
40
41 /*
42  * Copyright (C) 2002-2004  Motorola
43  * Copyright (C) 2006 Harald Welte <laforge@openezx.org>
44  *  07/28/2002  Initial version
45  *  11/18/2002  Second version
46  *  04/21/2004  Add GPRS PROC
47  *  09/28/2008  Porting to kernel 2.6.21 by Spreadtrum
48  *  11/08/2013  Add Multi-mux support
49 */
50 #include <linux/module.h>
51 #include <linux/types.h>
52 #include <linux/kernel.h>
53 #include <linux/errno.h>
54 #include <linux/fcntl.h>
55 #include <linux/string.h>
56 #include <linux/major.h>
57 #include <linux/init.h>
58 #include <linux/proc_fs.h>
59 #include <linux/delay.h>
60 #include <linux/kthread.h>
61 #include <linux/completion.h>
62 #include <linux/sprdmux.h>
63 #include <linux/slab.h>
64 #include <linux/proc_fs.h>
65 #include <linux/sched/rt.h>
66 #include <linux/version.h> 
67 #include <linux/seq_file.h>
68 #include <linux/vmalloc.h>
69 #include <linux/init.h>
70 #include <linux/module.h>
71 #include <linux/timer.h>
72 #include "ts0710.h"
73 #include "ts0710_mux.h"
74
75
76 #define TS0710MUX_GPRS_SESSION_MAX 3
77 #define TS0710MUX_MAJOR 250
78 #define TS0710MUX_MINOR_START 0
79 #define NR_MUXS 32
80
81 #define TS0710MUX_TIME_OUT 250  /* 2500ms, for BP UART hardware flow control AP UART  */
82
83 #define TS0710MUX_IO_DLCI_FC_ON 0x54F2
84 #define TS0710MUX_IO_DLCI_FC_OFF 0x54F3
85 #define TS0710MUX_IO_FC_ON 0x54F4
86 #define TS0710MUX_IO_FC_OFF 0x54F5
87
88 #define TS0710MUX_MAX_BUF_SIZE          (64*1024)
89 #define TS0710MUX_MAX_TOTAL_SIZE        (1024*1024)
90
91 #define TS0710MUX_SEND_BUF_OFFSET 10
92 #define TS0710MUX_SEND_BUF_SIZE (DEF_TS0710_MTU + TS0710MUX_SEND_BUF_OFFSET + 34)
93 #define TS0710MUX_RECV_BUF_SIZE TS0710MUX_SEND_BUF_SIZE
94
95 /*For BP UART problem Begin*/
96 #ifdef TS0710SEQ2
97 #define ACK_SPACE 0             /* 6 * 11(ACK frame size)  */
98 #else
99 #define ACK_SPACE 0             /* 6 * 7(ACK frame size)  */
100 #endif
101 /*For BP UART problem End*/
102
103 #define TS0710MUX_SERIAL_BUF_SIZE (DEF_TS0710_MTU + TS0710_MAX_HDR_SIZE + ACK_SPACE)    /* For BP UART problem: ACK_SPACE  */
104
105 #define TS0710MUX_MAX_TOTAL_FRAME_SIZE (DEF_TS0710_MTU + TS0710_MAX_HDR_SIZE + FLAG_SIZE)
106 #define TS0710MUX_MAX_CHARS_IN_BUF 65535
107 #define TS0710MUX_THROTTLE_THRESHOLD DEF_TS0710_MTU
108
109 #define TEST_PATTERN_SIZE 250
110
111 #define CMDTAG 0x55
112 #define DATATAG 0xAA
113
114 #define ACK 0x4F                /*For BP UART problem */
115
116 /*For BP UART problem Begin*/
117 #ifdef TS0710SEQ2
118 #define FIRST_BP_SEQ_OFFSET 0   /*offset from start flag */
119 #define SECOND_BP_SEQ_OFFSET 0  /*offset from start flag */
120 #define FIRST_AP_SEQ_OFFSET 0   /*offset from start flag */
121 #define SECOND_AP_SEQ_OFFSET 0  /*offset from start flag */
122 #define SLIDE_BP_SEQ_OFFSET 0   /*offset from start flag */
123 #define SEQ_FIELD_SIZE 0
124 #else
125 #define SLIDE_BP_SEQ_OFFSET  1  /*offset from start flag */
126 #define SEQ_FIELD_SIZE    0
127 #endif
128
129 #define ADDRESS_FIELD_OFFSET (1 + SEQ_FIELD_SIZE)       /*offset from start flag */
130 /*For BP UART problem End*/
131
132 #ifndef UNUSED_PARAM
133 #define UNUSED_PARAM(v) (void)(v)
134 #endif
135
136 #define TS0710MUX_GPRS1_DLCI  3
137 #define TS0710MUX_GPRS2_DLCI  4
138 #define TS0710MUX_VT_DLCI         2
139
140 #define TS0710MUX_GPRS1_RECV_COUNT_IDX 0
141 #define TS0710MUX_GPRS1_SEND_COUNT_IDX 1
142 #define TS0710MUX_GPRS2_RECV_COUNT_IDX 2
143 #define TS0710MUX_GPRS2_SEND_COUNT_IDX 3
144 #define TS0710MUX_VT_RECV_COUNT_IDX 4
145 #define TS0710MUX_VT_SEND_COUNT_IDX 5
146
147 #define TS0710MUX_COUNT_MAX_IDX        5
148 #define TS0710MUX_COUNT_IDX_NUM (TS0710MUX_COUNT_MAX_IDX + 1)
149
150 #define SPRDMUX_MAX_NUM SPRDMUX_ID_MAX
151
152 /* Bit number in flags of mux_send_struct */
153 #define RECV_RUNNING 0
154 #define MUX_MODE_MAX_LEN 11
155
156 #define MUX_STATE_NOT_READY 0
157 #define MUX_STATE_READY 1
158 #define MUX_STATE_CRASHED 3
159 #define MUX_STATE_RECOVERING 4
160
161 #define MUX_RIL_LINE_END 11
162
163 #define MUX_VETH_LINE_BEGIN 13
164 #define MUX_VETH_LINE_END 17
165 #define MUX_VETH_RINGBUFER_NUM 24
166
167 #define MUX_WATCH_INTERVAL      3 * HZ
168
169 /* Debug */
170 //#define TS0710DEBUG
171 //#define TS0710LOG
172
173 static __u8 line2dlci[NR_MUXS] =
174     { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ,14, 15, 16,
175                 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
176 typedef struct {
177         __u8 cmdline;
178         __u8 dataline;
179 } dlci_line;
180
181 static dlci_line dlci2line[] = {
182         {0, 0},                 /* DLCI 0 */
183         {0, 0},                 /* DLCI 1 */
184         {1, 1},                 /* DLCI 2 */
185         {2, 2},                 /* DLCI 3 */
186         {3, 3},                 /* DLCI 4 */
187         {4, 4},                 /* DLCI 5 */
188         {5, 5},                 /* DLCI 6 */
189         {6, 6},                 /* DLCI 7 */
190         {7, 7},                 /* DLCI 8 */
191         {8, 8},                 /* DLCI 9 */
192         {9, 9},                 /* DLCI 10 */
193         {10, 10},               /* DLCI 11 */
194         {11, 11},               /* DLCI 12 */
195         {12, 12},               /* DLCI 13 */
196         {13, 13},               /* DLCI 14 */
197         {14, 14},               /* DLCI 15 */
198         {15, 15},               /* DLCI 16 */
199         {16, 16},               /* DLCI 17 */
200         {17, 17},               /* DLCI 18 */
201         {18, 18},               /* DLCI 19 */
202         {19, 19},               /* DLCI 20 */
203         {20, 20},               /* DLCI 21 */
204         {21, 21},               /* DLCI 22 */
205         {22, 22},               /* DLCI 23 */
206         {23, 23},               /* DLCI 24 */
207         {24, 24},               /* DLCI 25 */
208         {25, 25},               /* DLCI 26 */
209         {26, 26},               /* DLCI 27 */
210         {27, 27},               /* DLCI 28 */
211         {28, 28},               /* DLCI 29 */
212         {29, 29},               /* DLCI 30 */
213         {30, 30},               /* DLCI 31 */
214         {31, 31},               /* DLCI 32 */
215 };
216
217 /* set line ring buffer num*/
218 static __u8 ringbuf_num[SPRDMUX_ID_MAX][NR_MUXS];
219
220 typedef struct {
221         __u8 *buf;
222         __u8 **frame;
223         unsigned long flags;
224         __u16 *length;
225         __u8 need_notify;
226
227         volatile __u8 dummy;    /* Allignment to 4*n bytes */
228         struct mutex send_lock;
229 //      struct mutex send_data_lock; /*Todo*/
230         __u32 read_index;
231         __u32 write_index;
232
233         wait_queue_head_t tx_wait;
234 } mux_send_struct;
235
236 struct mux_recv_packet_tag {
237         __u8 *data;
238         __u32 length;
239         __u32 pos;
240         struct mux_recv_packet_tag *next;
241 };
242 typedef struct mux_recv_packet_tag mux_recv_packet;
243
244 struct mux_recv_struct_tag {
245         __u8 data[TS0710MUX_RECV_BUF_SIZE];
246         __u32 length;
247         __u32 total;
248         __u32 pos;
249         mux_recv_packet *mux_packet;
250         struct mutex recv_lock;
251         struct mutex recv_data_lock;
252         wait_queue_head_t rx_wait;
253 };
254 typedef struct mux_recv_struct_tag mux_recv_struct;
255
256 struct notify {
257         notify_func func;
258         void *user_data;
259 };
260
261 struct sprd_mux {
262         SPRDMUX_ID_E mux_id;
263         int mux_exiting;
264         mux_send_struct *mux_send_info[NR_MUXS];
265         volatile __u8 mux_send_info_flags[NR_MUXS];
266         mux_recv_struct *mux_recv_info[NR_MUXS];
267         volatile __u8 mux_recv_info_flags[NR_MUXS];
268         struct completion send_completion;
269
270         struct task_struct *mux_recv_kthread;
271         struct task_struct *mux_send_kthread;
272
273         struct sprdmux *io_hal;
274         ts0710_con *connection;
275         volatile int cmux_mode;
276
277         struct notify callback[NR_MUXS];
278         struct mutex handshake_mutex;
279         struct mutex open_mutex[NR_MUXS];
280         volatile short int open_count[NR_MUXS];
281
282         __u32 check_read_sum[NR_MUXS];
283         __u32 check_write_sum[NR_MUXS];
284
285         wait_queue_head_t handshake_ready;
286         wait_queue_head_t modem_ready;
287         struct task_struct *mux_recover_kthread;
288         int mux_status;
289
290 /* receive_worker */
291         unsigned char tbuf[TS0710MUX_MAX_BUF_SIZE];
292         unsigned char *tbuf_ptr;
293         unsigned char *start_flag;
294         int framelen;
295         /*For BP UART problem Begin */
296         __u8 expect_seq;
297         /*For BP UART problem End */
298         struct timer_list watch_timer;
299
300 #ifdef TS0710DEBUG
301         unsigned char debug_hex_buf[TS0710MUX_MAX_BUF_SIZE];
302         unsigned char debug_str_buf[TS0710MUX_MAX_BUF_SIZE];
303 #endif
304
305 #ifdef TS0710LOG
306         unsigned char debug_frame_buf[TS0710MUX_MAX_BUF_SIZE];
307 #endif
308
309 } ;
310
311 typedef struct mux_info_{
312         SPRDMUX_ID_E mux_id;
313         char mux_name[SPRDMUX_MAX_NAME_LEN];
314         struct sprd_mux *handle;
315         struct sprdmux mux;
316
317 } mux_info;
318
319 static mux_info sprd_mux_mgr[SPRDMUX_MAX_NUM] =
320 {
321         [0] = {
322                         .mux_id = SPRDMUX_ID_SPI,
323                         .mux_name   = "spimux",
324                         .handle = NULL,
325         },
326         [1] = {
327                         .mux_id = SPRDMUX_ID_SDIO,
328                         .mux_name       = "sdiomux",
329                         .handle = NULL,
330         },
331 };
332
333 static void mux_print_mux_mgr(void);
334 static void mux_mgr_init(mux_info *mux_mgr);
335 static int mux_receive_thread(void *data);
336 static void mux_display_recv_info(const char * tag, int mux_id, int line);
337 static void receive_worker(struct sprd_mux *self, int start);
338 static int mux_mode = 0;
339
340 #ifdef min
341 #undef min
342 #define min(a,b)    ( (a)<(b) ? (a):(b) )
343 #endif
344
345 static int send_ua(ts0710_con * ts0710, __u8 dlci);
346 static int send_dm(ts0710_con * ts0710, __u8 dlci);
347 static int send_sabm(ts0710_con * ts0710, __u8 dlci);
348 static int send_disc(ts0710_con * ts0710, __u8 dlci);
349 static void queue_uih(mux_send_struct * send_info, __u32 ring_index, __u16 len, ts0710_con * ts0710, __u8 dlci);
350 static int send_pn_msg(ts0710_con * ts0710, __u8 prior, __u32 frame_size, __u8 credit_flow, __u8 credits, __u8 dlci, __u8 cr);
351 static int send_nsc_msg(ts0710_con * ts0710, mcc_type cmd, __u8 cr);
352 static void set_uih_hdr(short_frame * uih_pkt, __u8 dlci, __u32 len, __u8 cr);
353 static void mux_sched_send(struct sprd_mux *self);
354 static int ts0710_ctrl_channel_status(ts0710_con * ts0710);
355 static __u32 crc_check(__u8 * data, __u32 length, __u8 check_sum);
356 static __u8 crc_calc(__u8 * data, __u32 length);
357 static void create_crctable(__u8 table[]);
358 static __u8 crctable[256];
359
360 /* mux recover */
361 static int mux_handshake(struct sprd_mux *self);
362 static void mux_stop(struct sprd_mux *self);
363 static int mux_restore_channel(ts0710_con * ts0710);
364 static void mux_wakeup_all_read(struct sprd_mux *self);
365 static void mux_wakeup_all_write(struct sprd_mux *self);
366 static void mux_wakeup_all_opening(struct sprd_mux *self);
367 static void mux_wakeup_all_closing(struct sprd_mux *self);
368 static void mux_wakeup_all_wait(struct sprd_mux *self);
369
370 static void mux_tidy_buff(struct sprd_mux *self);
371 static void mux_recover(struct sprd_mux *self);
372 static int mux_recover_thread(void *data);
373 static int mux_restore_channel(ts0710_con * ts0710);
374 static void mux_display_connection(ts0710_con * ts0710, const char *tag);
375
376 static void mux_set_ringbuf_num(void);
377 static int mux_line_state(SPRDMUX_ID_E mux_id, int line);
378 static mux_send_struct * mux_alloc_send_info(SPRDMUX_ID_E mux_id, int line);
379 int sprdmux_line_busy(SPRDMUX_ID_E mux_id, int line);
380 void sprdmux_set_line_notify(SPRDMUX_ID_E mux_id, int line, __u8 notify);
381 static void mux_free_send_info(mux_send_struct * send_info);
382 static void display_send_info(char * tag, SPRDMUX_ID_E mux_id, int line);
383
384 static void mux_init_timer(struct sprd_mux *self);
385 static void mux_start_timer(struct sprd_mux *self);
386 static void mux_wathch_check(unsigned long priv);
387 static void mux_stop_timer(struct sprd_mux *self);
388
389 #ifdef TS0710DEBUG
390
391 #define TS0710_DEBUG(fmt, arg...) printk(KERN_INFO "MUX:%s "fmt, __FUNCTION__ , ## arg)
392 #define MUX_TS0710_DEBUG(mux_id, fmt, arg...) \
393 do \
394 {if (mux_id >= 0 && mux_id < SPRDMUX_ID_MAX)\
395 printk(KERN_INFO "[%s]: %s "fmt,sprd_mux_mgr[mux_id].mux_name, __FUNCTION__ , ## arg); \
396 } while (0)
397 #else
398 #define TS0710_DEBUG(fmt...)
399 #define MUX_TS0710_DEBUG(mux_id, fmt, arg...)
400 #endif /* End #ifdef TS0710DEBUG */
401
402 #ifdef TS0710LOG
403 #define TS0710_PRINTK(fmt, arg...) printk(fmt, ## arg)
404 #else
405 #define TS0710_PRINTK(fmt, arg...) printk(fmt, ## arg)
406 #endif /* End #ifdef TS0710LOG */
407
408 #ifdef TS0710DEBUG
409 static void MUX_TS0710_DEBUGHEX(SPRDMUX_ID_E mux_id, __u8 * buf, int len)
410 {
411         unsigned char *tbuf = NULL;
412         int i = 0;
413         int c = 0;
414
415         if (mux_id < 0 || mux_id >= SPRDMUX_ID_MAX || !buf || len <= 0) {
416                 printk(KERN_ERR "MUX: Error %s Invalid Param\n", __FUNCTION__);
417                 return;
418         }
419
420         if (!sprd_mux_mgr[mux_id].handle) {
421                 printk(KERN_ERR "MUX[%d]: Error %s mux_id Handle is 0\n", mux_id,  __FUNCTION__);
422                 mux_print_mux_mgr();
423                 return;
424         }
425
426         tbuf = sprd_mux_mgr[mux_id].handle->debug_hex_buf;
427
428         if (!tbuf) {
429                 printk(KERN_ERR "MUX[%d]: Error %s mux_id tbuf is NULL\n", mux_id,  __FUNCTION__);
430                 return;
431         }
432
433         for (i = 0; (i < len) && (c < (TS0710MUX_MAX_BUF_SIZE - 3)); i++) {
434                 sprintf(&tbuf[c], "%02x ", buf[i]);
435                 c += 3;
436         }
437         tbuf[c] = 0;
438
439         MUX_TS0710_DEBUG(mux_id, "%s", tbuf);
440 }
441
442 static void MUX_TS0710_DEBUGSTR(SPRDMUX_ID_E mux_id, __u8 * buf, int len)
443 {
444         unsigned char *tbuf = NULL;
445         struct sprd_mux *self = NULL;
446
447         if (mux_id < 0 || mux_id >= SPRDMUX_ID_MAX || !buf || len <= 0) {
448                 printk(KERN_ERR "MUX: Error %s Invalid Param\n", __FUNCTION__);
449                 return;
450         }
451
452         self = sprd_mux_mgr[mux_id].handle;
453         if (!self) {
454                 printk(KERN_ERR "MUX[%d]: Error %s self is NULL\n", mux_id,  __FUNCTION__);
455                 mux_print_mux_mgr();
456                 return;
457         }
458
459         tbuf = self->debug_str_buf;
460
461         if (!tbuf) {
462                 printk(KERN_ERR "MUX[%d]: Error %s mux_id tbuf is NULL\n", mux_id,  __FUNCTION__);
463                 return;
464         }
465
466         if (len > (TS0710MUX_MAX_BUF_SIZE - 1)) {
467                 len = (TS0710MUX_MAX_BUF_SIZE - 1);
468         }
469
470         memcpy(tbuf, buf, len);
471         tbuf[len] = 0;
472
473         /* 0x00 byte in the string pointed by tbuf may truncate the print result */
474         MUX_TS0710_DEBUG(mux_id, "%s", tbuf);
475 }
476 #else
477 #define MUX_TS0710_DEBUGHEX(mux_id, buf, len)
478 #define MUX_TS0710_DEBUGSTR(mux_id, buf, len)
479 #endif /* End #ifdef TS0710DEBUG */
480
481 #ifdef TS0710LOG
482 static void MUX_TS0710_LOGSTR_FRAME(SPRDMUX_ID_E mux_id, __u8 send, __u8 * data, int len)
483 {
484         unsigned char *tbuf = NULL;
485         short_frame *short_pkt;
486         long_frame *long_pkt;
487         __u8 *uih_data_start;
488         __u32 uih_len;
489         __u8 dlci;
490         int pos;
491         struct sprd_mux *self = NULL;
492
493         if (mux_id < 0 || mux_id >= SPRDMUX_ID_MAX || !data || len <= 0) {
494                 printk(KERN_ERR "MUX: Error %s Invalid Param\n", __FUNCTION__);
495                 return;
496         }
497
498         self = sprd_mux_mgr[mux_id].handle;
499         if (!self) {
500                 printk(KERN_ERR "MUX[%d]: Error %s self is NULL\n", mux_id,  __FUNCTION__);
501                 return;
502         }
503
504         tbuf = self->debug_frame_buf;
505
506         if (!tbuf) {
507                 printk(KERN_ERR "MUX[%d]: Error %s tbuf is NULL\n", mux_id,  __FUNCTION__);
508                 return;
509         }
510
511         if (len <= 0) {
512                 return;
513         }
514
515         pos = 0;
516         if (send) {
517                 pos += sprintf(&tbuf[pos], "<");
518                 short_pkt = (short_frame *) (data + 1);
519         } else {
520                 pos +=
521                     sprintf(&tbuf[pos], ">%d ",
522                             *(data + SLIDE_BP_SEQ_OFFSET));
523
524 #ifdef TS0710SEQ2
525                 pos +=
526                     sprintf(&tbuf[pos], "%02x %02x %02x %02x ",
527                             *(data + FIRST_BP_SEQ_OFFSET),
528                             *(data + SECOND_BP_SEQ_OFFSET),
529                             *(data + FIRST_AP_SEQ_OFFSET),
530                             *(data + SECOND_AP_SEQ_OFFSET));
531 #endif
532
533                 short_pkt = (short_frame *) (data + ADDRESS_FIELD_OFFSET);
534         }
535
536         dlci = short_pkt->h.addr.server_chn << 1 | short_pkt->h.addr.d;
537         switch (CLR_PF(short_pkt->h.control)) {
538         case SABM:
539                 pos += sprintf(&tbuf[pos], "C SABM %d ::", dlci);
540                 break;
541         case UA:
542                 pos += sprintf(&tbuf[pos], "C UA %d ::", dlci);
543                 break;
544         case DM:
545                 pos += sprintf(&tbuf[pos], "C DM %d ::", dlci);
546                 break;
547         case DISC:
548                 pos += sprintf(&tbuf[pos], "C DISC %d ::", dlci);
549                 break;
550
551         case ACK:
552                 pos += sprintf(&tbuf[pos], "C ACK %d ", short_pkt->data[0]);
553
554 #ifdef TS0710SEQ2
555                 pos +=
556                     sprintf(&tbuf[pos], "%02x %02x %02x %02x ",
557                             short_pkt->data[1], short_pkt->data[2],
558                             short_pkt->data[3], short_pkt->data[4]);
559 #endif
560
561                 pos += sprintf(&tbuf[pos], "::");
562                 break;
563
564         case UIH:
565                 if (!dlci) {
566                         pos += sprintf(&tbuf[pos], "C MCC %d ::", dlci);
567                 } else {
568
569                         if ((short_pkt->h.length.ea) == 0) {
570                                 long_pkt = (long_frame *) short_pkt;
571                                 uih_len = GET_LONG_LENGTH(long_pkt->h.length);
572                                 uih_data_start = long_pkt->h.data;
573                         } else {
574                                 uih_len = short_pkt->h.length.len;
575                                 uih_data_start = short_pkt->data;
576                         }
577                         switch (0) {
578                         case CMDTAG:
579                                 pos +=
580                                     sprintf(&tbuf[pos], "I %d A %d ::", dlci,
581                                             uih_len);
582                                 break;
583                         case DATATAG:
584                         default:
585                                 pos +=
586                                     sprintf(&tbuf[pos], "I %d D %d ::", dlci,
587                                             uih_len);
588                                 break;
589                         }
590
591                 }
592                 break;
593         default:
594                 pos += sprintf(&tbuf[pos], "N!!! %d ::", dlci);
595                 break;
596         }
597
598         if (len > (TS0710MUX_MAX_BUF_SIZE - pos - 1)) {
599                 len = (TS0710MUX_MAX_BUF_SIZE - pos - 1);
600         }
601
602         memcpy(&tbuf[pos], data, len);
603         pos += len;
604         tbuf[pos] = 0;
605
606         /* 0x00 byte in the string pointed by g_tbuf may truncate the print result */
607         TS0710_PRINTK("[%s]: %s\n", sprd_mux_mgr[mux_id].mux_name, tbuf);
608 }
609 #else
610 #define MUX_TS0710_LOGSTR_FRAME(mux_id, send, data, len)
611 #endif
612
613 #ifdef TS0710SIG
614 #define my_for_each_task(p) \
615         for ((p) = current; ((p) = (p)->next_task) != current; )
616
617 /* To be fixed */
618 static void TS0710_SIG2APLOGD(void)
619 {
620         struct task_struct *p;
621         static __u8 sig = 0;
622
623         if (sig) {
624                 return;
625         }
626
627         read_lock(&tasklist_lock);
628         my_for_each_task(p) {
629                 if (strncmp(p->comm, "aplogd", 6) == 0) {
630                         sig = 1;
631                         if (send_sig(SIGUSR2, p, 1) == 0) {
632                                 TS0710_PRINTK
633                                     ("MUX: success to send SIGUSR2 to aplogd!\n");
634                         } else {
635                                 TS0710_PRINTK
636                                     ("MUX: failure to send SIGUSR2 to aplogd!\n");
637                         }
638                         break;
639                 }
640         }
641         read_unlock(&tasklist_lock);
642
643         if (!sig) {
644                 TS0710_PRINTK("MUX: not found aplogd!\n");
645         }
646 }
647 #else
648 #define TS0710_SIG2APLOGD()
649 #endif
650
651 static int valid_dlci(__u8 dlci)
652 {
653         if ((dlci < TS0710_MAX_CHN) && (dlci > 0))
654                 return 1;
655         else
656                 return 0;
657 }
658
659 static int basic_write(ts0710_con * ts0710, __u8 * buf, int len)
660 {
661         int res, send;
662         struct sprd_mux *self = NULL;
663
664         if (!ts0710) {
665                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
666                 return 0;
667         }
668
669         self = (struct sprd_mux *)ts0710->user_data;
670
671         if (!self || !self->io_hal || !self->io_hal->io_write) {
672                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
673                 return 0;
674         }
675
676         buf[0] = TS0710_BASIC_FLAG;
677         buf[len + 1] = TS0710_BASIC_FLAG;
678
679         MUX_TS0710_LOGSTR_FRAME(self->mux_id, 1, buf, len + 2);
680         MUX_TS0710_DEBUGHEX(self->mux_id, buf, len + 2);
681         send = 0;
682
683         while (send < len + 2) {
684                 res = self->io_hal->io_write(buf + send, len + 2 - send);
685                 if (res < 0)
686                         return -EIO;
687                 else if (res == 0)
688                         msleep(2);
689                 else
690                         send = send + res;
691         }
692
693         return len + 2;
694 }
695
696 /* Functions for the crc-check and calculation */
697
698 #define CRC_VALID 0xcf
699
700 static __u32 crc_check(__u8 * data, __u32 length, __u8 check_sum)
701 {
702         __u8 fcs = 0xff;
703 #ifdef TS0710DEBUG
704         __u32 len = length;
705 #endif
706         length = length - 1;
707         while (length--) {
708                 fcs = crctable[fcs ^ *data++];
709         }
710         fcs = crctable[fcs ^ check_sum];
711         TS0710_DEBUG("fcs : %d\n", fcs);
712         TS0710_DEBUG(" crc_check :len:%d check_sum:%d fcs : %d\n", len,
713                      check_sum, fcs);
714         if (fcs == (uint) 0xcf) {       /*CRC_VALID) */
715                 TS0710_DEBUG("crc_check: CRC check OK\n");
716                 return 0;
717         } else {
718                 TS0710_PRINTK("MUX crc_check: CRC check failed\n");
719                 return 1;
720         }
721 }
722
723 /* Calculates the checksum according to the ts0710 specification */
724
725 static __u8 crc_calc(__u8 * data, __u32 length)
726 {
727         __u8 fcs = 0xff;
728
729         while (length--) {
730                 fcs = crctable[fcs ^ *data++];
731         }
732
733         return 0xff - fcs;
734 }
735
736 /* Calulates a reversed CRC table for the FCS check */
737
738 static void create_crctable(__u8 table[])
739 {
740         int i, j;
741
742         __u8 data;
743         __u8 code_word = (__u8) 0xe0;
744         __u8 sr = (__u8) 0;
745
746         for (j = 0; j < 256; j++) {
747                 data = (__u8) j;
748
749                 for (i = 0; i < 8; i++) {
750                         if ((data & 0x1) ^ (sr & 0x1)) {
751                                 sr >>= 1;
752                                 sr ^= code_word;
753                         } else {
754                                 sr >>= 1;
755                         }
756
757                         data >>= 1;
758                         sr &= 0xff;
759                 }
760
761                 table[j] = sr;
762                 sr = 0;
763         }
764 }
765
766 static void ts0710_reset_dlci(ts0710_con *ts0710, __u8 j)
767 {
768         if (j >= TS0710_MAX_CHN)
769                 return;
770
771         if (!ts0710) {
772                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
773                 return;
774         }
775
776         ts0710->dlci[j].state = DISCONNECTED;
777         ts0710->dlci[j].flow_control = 0;
778         ts0710->dlci[j].mtu = DEF_TS0710_MTU;
779         ts0710->dlci[j].initiated = 0;
780         ts0710->dlci[j].initiator = 0;
781 }
782
783 static void ts0710_reset_con(ts0710_con *ts0710)
784 {
785         __u8 j;
786
787         if (!ts0710) {
788                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
789                 return;
790         }
791
792         ts0710->initiator = 0;
793         ts0710->mtu = DEF_TS0710_MTU + TS0710_MAX_HDR_SIZE;
794         ts0710->be_testing = 0;
795         ts0710->test_errs = 0;
796
797         for (j = 0; j < TS0710_MAX_CHN; j++) {
798                 ts0710_reset_dlci(ts0710, j);
799         }
800 }
801
802 static void ts0710_init_waitqueue(ts0710_con *ts0710)
803 {
804         __u8 j;
805
806         if (!ts0710) {
807                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
808                 return;
809         }
810
811         init_waitqueue_head(&ts0710->test_wait);
812
813         for (j = 0; j < TS0710_MAX_CHN; j++) {
814                 init_waitqueue_head(&ts0710->dlci[j].open_wait);
815                 init_waitqueue_head(&ts0710->dlci[j].close_wait);
816         }
817 }
818
819 static void ts0710_init(ts0710_con *ts0710)
820 {
821         if (!ts0710) {
822                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
823                 return;
824         }
825
826         ts0710_reset_con(ts0710);
827 }
828
829 static void ts0710_upon_disconnect(ts0710_con *ts0710)
830 {
831         __u8 j;
832
833         if (!ts0710) {
834                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
835                 return;
836         }
837
838         for (j = 0; j < TS0710_MAX_CHN; j++) {
839                 ts0710->dlci[j].state = DISCONNECTED;
840                 wake_up_all(&ts0710->dlci[j].open_wait);
841                 wake_up_interruptible(&ts0710->dlci[j].close_wait);
842         }
843         ts0710->be_testing = 0;
844         wake_up_interruptible(&ts0710->test_wait);
845         ts0710_reset_con(ts0710);
846 }
847
848 /* Sending packet functions */
849
850 /* Creates a UA packet and puts it at the beginning of the pkt pointer */
851
852 static int send_ua(ts0710_con * ts0710, __u8 dlci)
853 {
854         __u8 buf[sizeof(short_frame) + FCS_SIZE + FLAG_SIZE];
855         short_frame *ua;
856
857
858         if (!ts0710) {
859                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
860                 return 0;
861         }
862
863         if (!ts0710->user_data) {
864                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
865                 return 0;
866         }
867
868         MUX_TS0710_DEBUG(((struct sprd_mux *)ts0710->user_data)->mux_id, "send_ua: Creating UA packet to DLCI %d\n", dlci);
869
870         ua = (short_frame *) (buf + 1);
871         ua->h.addr.ea = 1;
872         ua->h.addr.cr = ((~(ts0710->initiator)) & 0x1);
873         ua->h.addr.d = (dlci) & 0x1;
874         ua->h.addr.server_chn = (dlci) >> 0x1;
875         ua->h.control = SET_PF(UA);
876         ua->h.length.ea = 1;
877         ua->h.length.len = 0;
878         ua->data[0] = crc_calc((__u8 *) ua, SHORT_CRC_CHECK);
879
880         return basic_write(ts0710, buf, sizeof(short_frame) + FCS_SIZE);
881 }
882
883 /* Creates a DM packet and puts it at the beginning of the pkt pointer */
884
885 static int send_dm(ts0710_con * ts0710, __u8 dlci)
886 {
887         __u8 buf[sizeof(short_frame) + FCS_SIZE + FLAG_SIZE];
888         short_frame *dm;
889
890         if (!ts0710) {
891                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
892                 return 0;
893         }
894
895         if (!ts0710->user_data) {
896                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
897                 return 0;
898         }
899
900         MUX_TS0710_DEBUG(((struct sprd_mux *)ts0710->user_data)->mux_id, "send_dm: Creating DM packet to DLCI %d\n", dlci);
901
902         dm = (short_frame *) (buf + 1);
903         dm->h.addr.ea = 1;
904         dm->h.addr.cr = ((~(ts0710->initiator)) & 0x1);
905         dm->h.addr.d = dlci & 0x1;
906         dm->h.addr.server_chn = dlci >> 0x1;
907         dm->h.control = SET_PF(DM);
908         dm->h.length.ea = 1;
909         dm->h.length.len = 0;
910         dm->data[0] = crc_calc((__u8 *) dm, SHORT_CRC_CHECK);
911
912         return basic_write(ts0710, buf, sizeof(short_frame) + FCS_SIZE);
913 }
914
915 static int send_sabm(ts0710_con * ts0710, __u8 dlci)
916 {
917         __u8 buf[sizeof(short_frame) + FCS_SIZE + FLAG_SIZE];
918         short_frame *sabm;
919
920         if (!ts0710) {
921                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
922                 return 0;
923         }
924
925         if (!ts0710->user_data) {
926                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
927                 return 0;
928         }
929
930         MUX_TS0710_DEBUG(((struct sprd_mux *)ts0710->user_data)->mux_id, "send_sabm: Creating SABM packet to DLCI %d\n", dlci);
931
932         sabm = (short_frame *) (buf + 1);
933         sabm->h.addr.ea = 1;
934         sabm->h.addr.cr = ((ts0710->initiator) & 0x1);
935         sabm->h.addr.d = dlci & 0x1;
936         sabm->h.addr.server_chn = dlci >> 0x1;
937         sabm->h.control = SET_PF(SABM);
938         sabm->h.length.ea = 1;
939         sabm->h.length.len = 0;
940         sabm->data[0] = crc_calc((__u8 *) sabm, SHORT_CRC_CHECK);
941
942         return basic_write(ts0710, buf, sizeof(short_frame) + FCS_SIZE);
943 }
944
945 static int send_disc(ts0710_con * ts0710, __u8 dlci)
946 {
947         __u8 buf[sizeof(short_frame) + FCS_SIZE + FLAG_SIZE];
948         short_frame *disc;
949
950         if (!ts0710)
951         {
952                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
953                 return 0;
954         }
955
956         if (!ts0710->user_data)
957         {
958                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
959                 return 0;
960         }
961
962         MUX_TS0710_DEBUG(((struct sprd_mux *)ts0710->user_data)->mux_id, "send_disc: Creating DISC packet to DLCI %d\n", dlci);
963
964         disc = (short_frame *) (buf + 1);
965         disc->h.addr.ea = 1;
966         disc->h.addr.cr = ((ts0710->initiator) & 0x1);
967         disc->h.addr.d = dlci & 0x1;
968         disc->h.addr.server_chn = dlci >> 0x1;
969         disc->h.control = SET_PF(DISC);
970         disc->h.length.ea = 1;
971         disc->h.length.len = 0;
972         disc->data[0] = crc_calc((__u8 *) disc, SHORT_CRC_CHECK);
973
974         return basic_write(ts0710, buf, sizeof(short_frame) + FCS_SIZE);
975 }
976
977 static void queue_uih(mux_send_struct * send_info, __u32 ring_index, __u16 len,
978                       ts0710_con * ts0710, __u8 dlci)
979 {
980         __u32 size;
981
982         if (!ts0710 || !send_info) {
983                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
984                 return;
985         }
986
987         if (!ts0710->user_data) {
988                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
989                 return;
990         }
991
992         if (!send_info->frame) {
993                 printk(KERN_ERR "MUX: Error %s send_info->frame is NULL\n", __FUNCTION__);
994                 return;
995         }
996
997         MUX_TS0710_DEBUG(((struct sprd_mux *)ts0710->user_data)->mux_id,"queue_uih: Creating UIH packet with %d bytes data to DLCI %d\n", len, dlci);
998
999         if (len > SHORT_PAYLOAD_SIZE) {
1000                 long_frame *l_pkt;
1001
1002                 size = sizeof(long_frame) + len + FCS_SIZE;
1003                 l_pkt = (long_frame *) (send_info->frame[ring_index] - sizeof(long_frame));
1004                 set_uih_hdr((void *)l_pkt, dlci, len, ts0710->initiator);
1005                 l_pkt->data[len] = crc_calc((__u8 *) l_pkt, LONG_CRC_CHECK);
1006                 send_info->frame[ring_index] = ((__u8 *) l_pkt) - 1;
1007         } else {
1008                 short_frame *s_pkt;
1009
1010                 size = sizeof(short_frame) + len + FCS_SIZE;
1011                 s_pkt = (short_frame *) (send_info->frame[ring_index] - sizeof(short_frame));
1012                 set_uih_hdr((void *)s_pkt, dlci, len, ts0710->initiator);
1013                 s_pkt->data[len] = crc_calc((__u8 *) s_pkt, SHORT_CRC_CHECK);
1014                 send_info->frame[ring_index] = ((__u8 *) s_pkt) - 1;
1015         }
1016
1017         if (!send_info->length) {
1018                 printk(KERN_ERR "MUX: %s  pid[%d] send_info->length     NULL\n", __FUNCTION__, current->pid);
1019                 return;
1020         }
1021
1022         send_info->length[ring_index] = size;
1023 }
1024
1025 /* Multiplexer command packets functions */
1026
1027 /* Turns on the ts0710 flow control */
1028
1029 static int ts0710_fcon_msg(ts0710_con * ts0710, __u8 cr)
1030 {
1031         __u8 buf[30];
1032         mcc_short_frame *mcc_pkt;
1033         short_frame *uih_pkt;
1034         __u32 size;
1035
1036         if (!ts0710) {
1037                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
1038                 return 0;
1039         }
1040
1041         size = sizeof(short_frame) + sizeof(mcc_short_frame) + FCS_SIZE;
1042         uih_pkt = (short_frame *) (buf + 1);
1043         set_uih_hdr(uih_pkt, CTRL_CHAN, sizeof(mcc_short_frame), ts0710->initiator);
1044         uih_pkt->data[sizeof(mcc_short_frame)] = crc_calc((__u8 *) uih_pkt, SHORT_CRC_CHECK);
1045         mcc_pkt = (mcc_short_frame *) (uih_pkt->data);
1046
1047         mcc_pkt->h.type.ea = EA;
1048         mcc_pkt->h.type.cr = cr;
1049         mcc_pkt->h.type.type = FCON;
1050         mcc_pkt->h.length.ea = EA;
1051         mcc_pkt->h.length.len = 0;
1052
1053         return basic_write(ts0710, buf, size);
1054 }
1055
1056 /* Turns off the ts0710 flow control */
1057
1058 static int ts0710_fcoff_msg(ts0710_con * ts0710, __u8 cr)
1059 {
1060         __u8 buf[30];
1061         mcc_short_frame *mcc_pkt;
1062         short_frame *uih_pkt;
1063         __u32 size;
1064
1065         if (!ts0710) {
1066                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
1067                 return 0;
1068         }
1069
1070         size = (sizeof(short_frame) + sizeof(mcc_short_frame) + FCS_SIZE);
1071         uih_pkt = (short_frame *) (buf + 1);
1072         set_uih_hdr(uih_pkt, CTRL_CHAN, sizeof(mcc_short_frame), ts0710->initiator);
1073         uih_pkt->data[sizeof(mcc_short_frame)] = crc_calc((__u8 *) uih_pkt, SHORT_CRC_CHECK);
1074         mcc_pkt = (mcc_short_frame *) (uih_pkt->data);
1075
1076         mcc_pkt->h.type.ea = 1;
1077         mcc_pkt->h.type.cr = cr;
1078         mcc_pkt->h.type.type = FCOFF;
1079         mcc_pkt->h.length.ea = 1;
1080         mcc_pkt->h.length.len = 0;
1081
1082         return basic_write(ts0710, buf, size);
1083 }
1084
1085 /* Sends an PN-messages and sets the not negotiable parameters to their
1086    default values in ts0710 */
1087
1088 static int send_pn_msg(ts0710_con * ts0710, __u8 prior, __u32 frame_size,
1089                        __u8 credit_flow, __u8 credits, __u8 dlci, __u8 cr)
1090 {
1091         __u8 buf[30];
1092         pn_msg *pn_pkt;
1093         __u32 size;
1094
1095
1096         if (!ts0710) {
1097                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
1098                 return 0;
1099         }
1100
1101         if (!ts0710->user_data) {
1102                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
1103                 return 0;
1104         }
1105
1106         MUX_TS0710_DEBUG(((struct sprd_mux *)ts0710->user_data)->mux_id,
1107                                                 "send_pn_msg: DLCI 0x%02x, prior:0x%02x, frame_size:%d, credit_flow:%x, credits:%d, cr:%x\n",
1108                                                 dlci, prior, frame_size, credit_flow, credits, cr);
1109
1110         size = sizeof(pn_msg);
1111         pn_pkt = (pn_msg *) (buf + 1);
1112
1113         set_uih_hdr((void *)pn_pkt, CTRL_CHAN, size - (sizeof(short_frame) + FCS_SIZE), ts0710->initiator);
1114         pn_pkt->fcs = crc_calc((__u8 *) pn_pkt, SHORT_CRC_CHECK);
1115
1116         pn_pkt->mcc_s_head.type.ea = 1;
1117         pn_pkt->mcc_s_head.type.cr = cr;
1118         pn_pkt->mcc_s_head.type.type = PN;
1119         pn_pkt->mcc_s_head.length.ea = 1;
1120         pn_pkt->mcc_s_head.length.len = 8;
1121
1122         pn_pkt->res1 = 0;
1123         pn_pkt->res2 = 0;
1124         pn_pkt->dlci = dlci;
1125         pn_pkt->frame_type = 0;
1126         pn_pkt->credit_flow = credit_flow;
1127         pn_pkt->prior = prior;
1128         pn_pkt->ack_timer = 0;
1129         SET_PN_MSG_FRAME_SIZE(pn_pkt, frame_size);
1130         pn_pkt->credits = credits;
1131         pn_pkt->max_nbrof_retrans = 0;
1132
1133         return basic_write(ts0710, buf, size);
1134 }
1135
1136 /* Send a Not supported command - command, which needs 3 bytes */
1137
1138 static int send_nsc_msg(ts0710_con * ts0710, mcc_type cmd, __u8 cr)
1139 {
1140         __u8 buf[30];
1141         nsc_msg *nsc_pkt;
1142         __u32 size;
1143
1144         size = sizeof(nsc_msg);
1145         nsc_pkt = (nsc_msg *) (buf + 1);
1146
1147         if (!ts0710) {
1148                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
1149                 return 0;
1150         }
1151
1152         set_uih_hdr((void *)nsc_pkt, CTRL_CHAN, sizeof(nsc_msg) - sizeof(short_frame) - FCS_SIZE, ts0710->initiator);
1153
1154         nsc_pkt->fcs = crc_calc((__u8 *) nsc_pkt, SHORT_CRC_CHECK);
1155
1156         nsc_pkt->mcc_s_head.type.ea = 1;
1157         nsc_pkt->mcc_s_head.type.cr = cr;
1158         nsc_pkt->mcc_s_head.type.type = NSC;
1159         nsc_pkt->mcc_s_head.length.ea = 1;
1160         nsc_pkt->mcc_s_head.length.len = 1;
1161
1162         nsc_pkt->command_type.ea = 1;
1163         nsc_pkt->command_type.cr = cmd.cr;
1164         nsc_pkt->command_type.type = cmd.type;
1165
1166         return basic_write(ts0710, buf, size);
1167 }
1168
1169 static int ts0710_msc_msg(ts0710_con * ts0710, __u8 value, __u8 cr, __u8 dlci)
1170 {
1171         __u8 buf[30];
1172         msc_msg *msc_pkt;
1173         __u32 size;
1174
1175         size = sizeof(msc_msg);
1176         msc_pkt = (msc_msg *) (buf + 1);
1177
1178         if (!ts0710) {
1179                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
1180                 return 0;
1181         }
1182
1183         set_uih_hdr((void *)msc_pkt, CTRL_CHAN, sizeof(msc_msg) - sizeof(short_frame) - FCS_SIZE, ts0710->initiator);
1184
1185         msc_pkt->fcs = crc_calc((__u8 *) msc_pkt, SHORT_CRC_CHECK);
1186
1187         msc_pkt->mcc_s_head.type.ea = 1;
1188         msc_pkt->mcc_s_head.type.cr = cr;
1189         msc_pkt->mcc_s_head.type.type = MSC;
1190         msc_pkt->mcc_s_head.length.ea = 1;
1191         msc_pkt->mcc_s_head.length.len = 2;
1192
1193         msc_pkt->dlci.ea = 1;
1194         msc_pkt->dlci.cr = 1;
1195         msc_pkt->dlci.d = dlci & 1;
1196         msc_pkt->dlci.server_chn = (dlci >> 1) & 0x1f;
1197
1198         msc_pkt->v24_sigs = value;
1199
1200         return basic_write(ts0710, buf, size);
1201 }
1202
1203 static int ts0710_test_msg(ts0710_con * ts0710, __u8 * test_pattern, __u32 len,
1204                            __u8 cr, __u8 * f_buf)
1205 {
1206         __u32 size;
1207
1208         if (!ts0710 || !test_pattern || !f_buf)
1209         {
1210                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
1211                 return 0;
1212         }
1213
1214         if (len > SHORT_PAYLOAD_SIZE) {
1215                 long_frame *uih_pkt;
1216                 mcc_long_frame *mcc_pkt;
1217
1218                 size = (sizeof(long_frame) + sizeof(mcc_long_frame) + len + FCS_SIZE);
1219                 uih_pkt = (long_frame *) (f_buf + 1);
1220
1221                 set_uih_hdr((short_frame *) uih_pkt, CTRL_CHAN, len + sizeof(mcc_long_frame), ts0710->initiator);
1222                 uih_pkt->data[GET_LONG_LENGTH(uih_pkt->h.length)] = crc_calc((__u8 *) uih_pkt, LONG_CRC_CHECK);
1223                 mcc_pkt = (mcc_long_frame *) uih_pkt->data;
1224
1225                 mcc_pkt->h.type.ea = EA;
1226                 /* cr tells whether it is a commmand (1) or a response (0) */
1227                 mcc_pkt->h.type.cr = cr;
1228                 mcc_pkt->h.type.type = TEST;
1229                 SET_LONG_LENGTH(mcc_pkt->h.length, len);
1230                 memcpy(mcc_pkt->value, test_pattern, len);
1231         } else if (len > (SHORT_PAYLOAD_SIZE - sizeof(mcc_short_frame))) {
1232                 long_frame *uih_pkt;
1233                 mcc_short_frame *mcc_pkt;
1234
1235                 /* Create long uih packet and short mcc packet */
1236                 size =
1237                     (sizeof(long_frame) + sizeof(mcc_short_frame) + len +
1238                      FCS_SIZE);
1239                 uih_pkt = (long_frame *) (f_buf + 1);
1240
1241                 set_uih_hdr((short_frame *) uih_pkt, CTRL_CHAN, len + sizeof(mcc_short_frame), ts0710->initiator);
1242                 uih_pkt->data[GET_LONG_LENGTH(uih_pkt->h.length)] = crc_calc((__u8 *) uih_pkt, LONG_CRC_CHECK);
1243                 mcc_pkt = (mcc_short_frame *) uih_pkt->data;
1244
1245                 mcc_pkt->h.type.ea = EA;
1246                 mcc_pkt->h.type.cr = cr;
1247                 mcc_pkt->h.type.type = TEST;
1248                 mcc_pkt->h.length.ea = EA;
1249                 mcc_pkt->h.length.len = len;
1250                 memcpy(mcc_pkt->value, test_pattern, len);
1251         } else {
1252                 short_frame *uih_pkt;
1253                 mcc_short_frame *mcc_pkt;
1254
1255                 size = (sizeof(short_frame) + sizeof(mcc_short_frame) + len + FCS_SIZE);
1256                 uih_pkt = (short_frame *) (f_buf + 1);
1257
1258                 set_uih_hdr((void *)uih_pkt, CTRL_CHAN, len
1259                             + sizeof(mcc_short_frame), ts0710->initiator);
1260                 uih_pkt->data[uih_pkt->h.length.len] =
1261                     crc_calc((__u8 *) uih_pkt, SHORT_CRC_CHECK);
1262                 mcc_pkt = (mcc_short_frame *) uih_pkt->data;
1263
1264                 mcc_pkt->h.type.ea = EA;
1265                 mcc_pkt->h.type.cr = cr;
1266                 mcc_pkt->h.type.type = TEST;
1267                 mcc_pkt->h.length.ea = EA;
1268                 mcc_pkt->h.length.len = len;
1269                 memcpy(mcc_pkt->value, test_pattern, len);
1270
1271         }
1272         return basic_write(ts0710, f_buf, size);
1273 }
1274
1275 static void set_uih_hdr(short_frame * uih_pkt, __u8 dlci, __u32 len, __u8 cr)
1276 {
1277         uih_pkt->h.addr.ea = 1;
1278         uih_pkt->h.addr.cr = cr;
1279         uih_pkt->h.addr.d = dlci & 0x1;
1280         uih_pkt->h.addr.server_chn = dlci >> 1;
1281         uih_pkt->h.control = CLR_PF(UIH);
1282
1283         if (len > SHORT_PAYLOAD_SIZE) {
1284                 SET_LONG_LENGTH(((long_frame *) uih_pkt)->h.length, len);
1285         } else {
1286                 uih_pkt->h.length.ea = 1;
1287                 uih_pkt->h.length.len = len;
1288         }
1289 }
1290
1291 /* Parses a multiplexer control channel packet */
1292
1293 static void process_mcc(__u8 * data, __u32 len, ts0710_con * ts0710, int longpkt)
1294 {
1295         __u8 *tbuf = NULL;
1296         mcc_short_frame *mcc_short_pkt;
1297         struct sprd_mux *self = NULL;
1298         int j;
1299
1300         TS0710_DEBUG("process_mcc\n");
1301
1302         if (!ts0710 || !data) {
1303                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
1304                 return;
1305         }
1306
1307         self = (struct sprd_mux *)ts0710->user_data;
1308         if (!self) {
1309                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
1310                 return;
1311         }
1312
1313         if (longpkt) {
1314                 mcc_short_pkt = (mcc_short_frame *) (((long_frame *) data)->data);
1315         } else {
1316                 mcc_short_pkt = (mcc_short_frame *) (((short_frame *) data)->data);
1317         }
1318
1319         switch (mcc_short_pkt->h.type.type) {
1320         case TEST:
1321                 if (mcc_short_pkt->h.type.cr == MCC_RSP) {
1322                         MUX_TS0710_DEBUG(self->mux_id, "Received test command response\n");
1323
1324                         if (ts0710->be_testing) {
1325                                 if ((mcc_short_pkt->h.length.ea) == 0) {
1326                                         mcc_long_frame *mcc_long_pkt;
1327                                         mcc_long_pkt = (mcc_long_frame *) mcc_short_pkt;
1328                                         if (GET_LONG_LENGTH
1329                                             (mcc_long_pkt->h.length) !=
1330                                             TEST_PATTERN_SIZE) {
1331                                                 ts0710->test_errs = TEST_PATTERN_SIZE;
1332                                                         MUX_TS0710_DEBUG(self->mux_id, "Err: received test pattern is %d bytes long, not expected %d\n", GET_LONG_LENGTH(mcc_long_pkt->h.length), TEST_PATTERN_SIZE);
1333                                         } else {
1334                                                 ts0710->test_errs = 0;
1335                                                 for (j = 0; j < TEST_PATTERN_SIZE; j++) {
1336                                                         if (mcc_long_pkt->value[j] != (j & 0xFF)) {
1337                                                                 (ts0710->test_errs)++;
1338                                                         }
1339                                                 }
1340                                         }
1341
1342                                 } else {
1343
1344 #if TEST_PATTERN_SIZE < 128
1345                                         if (mcc_short_pkt->h.length.len != TEST_PATTERN_SIZE) {
1346 #endif
1347
1348                                                 ts0710->test_errs = TEST_PATTERN_SIZE;
1349                                                         MUX_TS0710_DEBUG(self->mux_id, "Err: received test pattern is %d bytes long, not expected %d\n", mcc_short_pkt->h.length.len, TEST_PATTERN_SIZE);
1350
1351 #if TEST_PATTERN_SIZE < 128
1352                                         } else {
1353                                                 ts0710->test_errs = 0;
1354                                                 for (j = 0; j < TEST_PATTERN_SIZE; j++) {
1355                                                         if (mcc_short_pkt->value[j] != (j & 0xFF)) {
1356                                                                 (ts0710->test_errs)++;
1357                                                         }
1358                                                 }
1359                                         }
1360 #endif
1361
1362                                 }
1363
1364                                 ts0710->be_testing = 0; /* Clear the flag */
1365                                 wake_up_interruptible(&ts0710->test_wait);
1366                         } else {
1367                                 MUX_TS0710_DEBUG(self->mux_id, "Err: shouldn't or late to get test cmd response\n");
1368                         }
1369                 } else {
1370                         tbuf = (__u8 *) kmalloc(len + 32, GFP_ATOMIC);
1371                         if (!tbuf) {
1372                                 break;
1373                         }
1374
1375                         if ((mcc_short_pkt->h.length.ea) == 0) {
1376                                 mcc_long_frame *mcc_long_pkt;
1377                                 mcc_long_pkt = (mcc_long_frame *) mcc_short_pkt;
1378                                 ts0710_test_msg(ts0710, mcc_long_pkt->value,
1379                                                 GET_LONG_LENGTH(mcc_long_pkt->h.
1380                                                                 length),
1381                                                 MCC_RSP, tbuf);
1382                         } else {
1383                                 ts0710_test_msg(ts0710, mcc_short_pkt->value,
1384                                                 mcc_short_pkt->h.length.len,
1385                                                 MCC_RSP, tbuf);
1386                         }
1387
1388                         kfree(tbuf);
1389                 }
1390                 break;
1391
1392         case FCON:              /*Flow control on command */
1393                 MUX_TS0710_DEBUG(self->mux_id, "MUX Received Flow control(all channels) on command\n");
1394                 if (mcc_short_pkt->h.type.cr == MCC_CMD) {
1395                         ts0710->dlci[0].state = CONNECTED;
1396                         ts0710_fcon_msg(ts0710, MCC_RSP);
1397                         mux_sched_send(self);
1398                 }
1399                 break;
1400
1401         case FCOFF:             /*Flow control off command */
1402                 MUX_TS0710_DEBUG(self->mux_id, "MUX Received Flow control(all channels) off command\n");
1403                 if (mcc_short_pkt->h.type.cr == MCC_CMD) {
1404                         for (j = 0; j < TS0710_MAX_CHN; j++) {
1405                                 ts0710->dlci[j].state = FLOW_STOPPED;
1406                         }
1407                         ts0710_fcoff_msg(ts0710, MCC_RSP);
1408                 }
1409                 break;
1410
1411         case MSC:               /*Modem status command */
1412                 {
1413                         __u8 dlci;
1414                         __u8 v24_sigs;
1415
1416                         dlci = (mcc_short_pkt->value[0]) >> 2;
1417                         v24_sigs = mcc_short_pkt->value[1];
1418
1419                         if ((ts0710->dlci[dlci].state != CONNECTED)
1420                             && (ts0710->dlci[dlci].state != FLOW_STOPPED)) {
1421                                 MUX_TS0710_DEBUG(self->mux_id, "Received Modem status dlci = %d\n",dlci);
1422                                 send_dm(ts0710, dlci);
1423                                 break;
1424                         }
1425                         if (mcc_short_pkt->h.type.cr == MCC_CMD) {
1426                                 MUX_TS0710_DEBUG(self->mux_id, "Received Modem status command\n");
1427                                 if (v24_sigs & 2) {
1428                                         if (ts0710->dlci[dlci].state ==
1429                                             CONNECTED) {
1430                                                 MUX_TS0710_DEBUG(self->mux_id, "MUX Received Flow off on dlci %d\n",
1431                                                      dlci);
1432                                                 ts0710->dlci[dlci].state =
1433                                                     FLOW_STOPPED;
1434                                         }
1435                                 } else {
1436                                         if (ts0710->dlci[dlci].state ==
1437                                             FLOW_STOPPED) {
1438                                                 ts0710->dlci[dlci].state =
1439                                                     CONNECTED;
1440                                                 MUX_TS0710_DEBUG(self->mux_id, "MUX Received Flow on on dlci %d\n",
1441                                                      dlci);
1442                                                 mux_sched_send(self);
1443                                         }
1444                                 }
1445
1446                                 ts0710_msc_msg(ts0710, v24_sigs, MCC_RSP, dlci);
1447
1448                         } else {
1449                                 MUX_TS0710_DEBUG(self->mux_id, "Received Modem status response\n");
1450
1451                                 if (v24_sigs & 2) {
1452                                         MUX_TS0710_DEBUG(self->mux_id, "Flow stop accepted\n");
1453                                 }
1454                         }
1455                         break;
1456                 }
1457
1458         case PN:                /*DLC parameter negotiation */
1459                 {
1460                         __u8 dlci;
1461                         __u16 frame_size;
1462                         pn_msg *pn_pkt;
1463
1464                         pn_pkt = (pn_msg *) data;
1465                         dlci = pn_pkt->dlci;
1466                         frame_size = GET_PN_MSG_FRAME_SIZE(pn_pkt);
1467                         MUX_TS0710_DEBUG(self->mux_id, "Received DLC parameter negotiation, PN\n");
1468                         if (pn_pkt->mcc_s_head.type.cr == MCC_CMD) {
1469                                 MUX_TS0710_DEBUG(self->mux_id, "received PN command with:\n");
1470                                 MUX_TS0710_DEBUG(self->mux_id, "Frame size:%d\n", frame_size);
1471
1472                                 frame_size =
1473                                     min(frame_size, ts0710->dlci[dlci].mtu);
1474                                 send_pn_msg(ts0710, pn_pkt->prior, frame_size,
1475                                             0, 0, dlci, MCC_RSP);
1476                                 ts0710->dlci[dlci].mtu = frame_size;
1477                                 MUX_TS0710_DEBUG(self->mux_id, "process_mcc : mtu set to %d\n",
1478                                              ts0710->dlci[dlci].mtu);
1479                         } else {
1480                                 MUX_TS0710_DEBUG(self->mux_id, "received PN response with:\n");
1481                                 MUX_TS0710_DEBUG(self->mux_id, "Frame size:%d\n", frame_size);
1482
1483                                 frame_size =
1484                                     min(frame_size, ts0710->dlci[dlci].mtu);
1485                                 ts0710->dlci[dlci].mtu = frame_size;
1486
1487                                 MUX_TS0710_DEBUG(self->mux_id, 
1488                                     "process_mcc : mtu set on dlci:%d to %d\n",
1489                                      dlci, ts0710->dlci[dlci].mtu);
1490
1491                                 if (ts0710->dlci[dlci].state == NEGOTIATING) {
1492                                         ts0710->dlci[dlci].state = CONNECTING;
1493                                         wake_up_all(&ts0710->dlci[dlci].open_wait);
1494                                 }
1495                         }
1496                         break;
1497                 }
1498
1499         case NSC:               /*Non supported command resonse */
1500                 MUX_TS0710_DEBUG(self->mux_id, "MUX Received Non supported command response\n");
1501                 break;
1502
1503         default:                /*Non supported command received */
1504                 MUX_TS0710_DEBUG(self->mux_id, "MUX Received a non supported command\n");
1505                 send_nsc_msg(ts0710, mcc_short_pkt->h.type, MCC_RSP);
1506                 break;
1507         }
1508 }
1509
1510 static mux_recv_packet *get_mux_recv_packet(__u32 size)
1511 {
1512         mux_recv_packet *recv_packet;
1513
1514         recv_packet = (mux_recv_packet *) kmalloc(sizeof(mux_recv_packet), GFP_ATOMIC);
1515         if (!recv_packet) {
1516                 return 0;
1517         }
1518
1519         recv_packet->data = (__u8 *) kmalloc(size, GFP_ATOMIC);
1520         if (!(recv_packet->data)) {
1521                 kfree(recv_packet);
1522                 return 0;
1523         }
1524         recv_packet->length = 0;
1525         recv_packet->next = 0;
1526         recv_packet->pos = 0;
1527
1528         return recv_packet;
1529 }
1530
1531 static void free_mux_recv_packet(mux_recv_packet * recv_packet)
1532 {
1533         if (!recv_packet) {
1534                 return;
1535         }
1536
1537         if (recv_packet->data) {
1538                 kfree(recv_packet->data);
1539         }
1540         kfree(recv_packet);
1541 }
1542
1543 static void free_mux_recv_struct(mux_recv_struct * recv_info)
1544 {
1545         mux_recv_packet *recv_packet1, *recv_packet2;
1546
1547         if (!recv_info) {
1548                 return;
1549         }
1550
1551         recv_packet1 = recv_info->mux_packet;
1552         while (recv_packet1) {
1553                 recv_packet2 = recv_packet1->next;
1554                 free_mux_recv_packet(recv_packet1);
1555                 recv_packet1 = recv_packet2;
1556         }
1557
1558         kfree(recv_info);
1559 }
1560
1561 static int ts0710_recv_data(ts0710_con * ts0710, char *data, int len)
1562 {
1563         short_frame *short_pkt;
1564         long_frame *long_pkt;
1565         __u8 *uih_data_start;
1566         __u32 uih_len;
1567         __u8 dlci;
1568         __u8 be_connecting;
1569         struct sprd_mux *self = NULL;
1570
1571         if (!ts0710 || !data) {
1572                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
1573                 return 0;
1574         }
1575
1576         self = (struct sprd_mux *)ts0710->user_data;
1577
1578         if (!self) {
1579                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
1580                 return 0;
1581         }
1582
1583         short_pkt = (short_frame *) data;
1584
1585         dlci = short_pkt->h.addr.server_chn << 1 | short_pkt->h.addr.d;
1586         MUX_TS0710_DEBUG(self->mux_id, "MUX ts0710_recv_data dlci = %d\n",dlci);
1587         switch (CLR_PF(short_pkt->h.control)) {
1588         case SABM:
1589                 MUX_TS0710_DEBUG(self->mux_id, "SABM-packet received\n");
1590
1591                 if (!dlci) {
1592                         MUX_TS0710_DEBUG(self->mux_id, "server channel == 0\n");
1593                         ts0710->dlci[0].state = CONNECTED;
1594
1595                         MUX_TS0710_DEBUG(self->mux_id, "sending back UA - control channel\n");
1596                         send_ua(ts0710, dlci);
1597                         wake_up_all(&ts0710->dlci[0].open_wait);
1598
1599                 } else if (valid_dlci(dlci)) {
1600
1601                         MUX_TS0710_DEBUG(self->mux_id, "Incomming connect on channel %d\n", dlci);
1602
1603                         MUX_TS0710_DEBUG(self->mux_id, "sending UA, dlci %d\n", dlci);
1604                         send_ua(ts0710, dlci);
1605
1606                         ts0710->dlci[dlci].state = CONNECTED;
1607                         wake_up_all(&ts0710->dlci[dlci].open_wait);
1608
1609                 } else {
1610                         MUX_TS0710_DEBUG(self->mux_id, "invalid dlci %d, sending DM\n", dlci);
1611                         send_dm(ts0710, dlci);
1612                 }
1613
1614                 break;
1615
1616         case UA:
1617                 printk(KERN_INFO "MUX: id[%d] dlci = %d UA packet received\n", self->mux_id, dlci);
1618
1619                 if (!dlci) {
1620                         MUX_TS0710_DEBUG(self->mux_id, "server channel == 0|dlci[0].state=%d\n",
1621                                      ts0710->dlci[0].state);
1622
1623                         if (ts0710->dlci[0].state == CONNECTING) {
1624                                 ts0710->dlci[0].state = CONNECTED;
1625                                 wake_up_all(&ts0710->dlci[0].open_wait);
1626                         } else if (ts0710->dlci[0].state == DISCONNECTING) {
1627                                 ts0710_upon_disconnect(ts0710);
1628                         } else {
1629                                 MUX_TS0710_DEBUG(self->mux_id, " Something wrong receiving UA packet\n");
1630                         }
1631                 } else if (valid_dlci(dlci)) {
1632                         MUX_TS0710_DEBUG(self->mux_id, "Incomming UA on channel %d|dlci[%d].state=%d\n",
1633                              dlci, dlci, ts0710->dlci[dlci].state);
1634
1635                         if (ts0710->dlci[dlci].state == CONNECTING) {
1636                                 ts0710->dlci[dlci].state = CONNECTED;
1637                                 wake_up_all(&ts0710->dlci[dlci].open_wait);
1638                         } else if (ts0710->dlci[dlci].state == DISCONNECTING) {
1639                                 ts0710->dlci[dlci].state = DISCONNECTED;
1640                                 wake_up_all(&ts0710->dlci[dlci].open_wait);
1641                                 wake_up_interruptible(&ts0710->dlci[dlci].close_wait);
1642                                 ts0710_reset_dlci(ts0710, dlci);
1643                         } else {
1644                                 /* Should NOT be here */
1645                                 ts0710->dlci[dlci].state = DISCONNECTED;
1646                                 wake_up_all(&ts0710->dlci[dlci].open_wait);
1647                                 wake_up_interruptible(&ts0710->dlci[dlci].close_wait);
1648                                 ts0710_reset_dlci(ts0710, dlci);
1649
1650                                 printk(KERN_ERR "MUX: id[%d] dlci[%d] wrong receiving UA packet state = %d\n", self->mux_id, dlci, ts0710->dlci[dlci].state);
1651                         }
1652                 } else {
1653                         MUX_TS0710_DEBUG(self->mux_id, "invalid dlci %d\n", dlci);
1654                 }
1655
1656                 break;
1657
1658         case DM:
1659                 MUX_TS0710_DEBUG(self->mux_id, "DM packet received\n");
1660
1661                 if (!dlci) {
1662                         MUX_TS0710_DEBUG(self->mux_id, "server channel == 0\n");
1663
1664                         if (ts0710->dlci[0].state == CONNECTING) {
1665                                 be_connecting = 1;
1666                         } else {
1667                                 be_connecting = 0;
1668                         }
1669                         ts0710_upon_disconnect(ts0710);
1670                         if (be_connecting) {
1671                                 ts0710->dlci[0].state = REJECTED;
1672                         }
1673                 } else if (valid_dlci(dlci)) {
1674                         MUX_TS0710_DEBUG(self->mux_id, "Incomming DM on channel %d\n", dlci);
1675
1676                         if (ts0710->dlci[dlci].state == CONNECTING) {
1677                                 ts0710->dlci[dlci].state = REJECTED;
1678                         } else {
1679                                 ts0710->dlci[dlci].state = DISCONNECTED;
1680                         }
1681                         wake_up_all(&ts0710->dlci[dlci].open_wait);
1682                         wake_up_interruptible(&ts0710->dlci[dlci].close_wait);
1683                         ts0710_reset_dlci(ts0710, dlci);
1684                 } else {
1685                         MUX_TS0710_DEBUG(self->mux_id, "invalid dlci %d\n", dlci);
1686                 }
1687
1688                 break;
1689         case DISC:
1690                 MUX_TS0710_DEBUG(self->mux_id, "DISC packet received\n");
1691
1692                 if (!dlci) {
1693                         MUX_TS0710_DEBUG(self->mux_id, "server channel == 0\n");
1694
1695                         send_ua(ts0710, dlci);
1696                         MUX_TS0710_DEBUG(self->mux_id, "DISC, sending back UA\n");
1697
1698                         ts0710_upon_disconnect(ts0710);
1699                 } else if (valid_dlci(dlci)) {
1700                         MUX_TS0710_DEBUG(self->mux_id, "Incomming DISC on channel %d\n", dlci);
1701
1702                         send_ua(ts0710, dlci);
1703                         MUX_TS0710_DEBUG(self->mux_id, "DISC, sending back UA\n");
1704
1705                         ts0710->dlci[dlci].state = DISCONNECTED;
1706                         wake_up_all(&ts0710->dlci[dlci].open_wait);
1707                         wake_up_interruptible(&ts0710->dlci[dlci].close_wait);
1708                         ts0710_reset_dlci(ts0710, dlci);
1709                 } else {
1710                         MUX_TS0710_DEBUG(self->mux_id, "invalid dlci %d\n", dlci);
1711                 }
1712
1713                 break;
1714
1715         case UIH:
1716                 MUX_TS0710_DEBUG(self->mux_id, "UIH packet received\n");
1717
1718                 if ((dlci >= TS0710_MAX_CHN)) {
1719                         MUX_TS0710_DEBUG(self->mux_id, "invalid dlci %d\n", dlci);
1720                         send_dm(ts0710, dlci);
1721                         break;
1722                 }
1723
1724                 if (GET_PF(short_pkt->h.control)) {
1725                         MUX_TS0710_DEBUG(self->mux_id, "Error UIH packet with P/F set, discard it!\n");
1726                         break;
1727                 }
1728
1729                 if ((ts0710->dlci[dlci].state != CONNECTED)
1730                     && (ts0710->dlci[dlci].state != FLOW_STOPPED)) {
1731                         MUX_TS0710_DEBUG(self->mux_id, "Error DLCI %d not connected, discard it!\n", dlci);
1732                         send_dm(ts0710, dlci);
1733                         break;
1734                 }
1735
1736                 if ((short_pkt->h.length.ea) == 0) {
1737                         MUX_TS0710_DEBUG(self->mux_id, "Long UIH packet received\n");
1738                         long_pkt = (long_frame *) data;
1739                         uih_len = GET_LONG_LENGTH(long_pkt->h.length);
1740                         uih_data_start = long_pkt->h.data;
1741                         MUX_TS0710_DEBUG(self->mux_id, "long packet length %d\n", uih_len);
1742
1743                 } else {
1744                         MUX_TS0710_DEBUG(self->mux_id, "Short UIH pkt received\n");
1745                         uih_len = short_pkt->h.length.len;
1746                         uih_data_start = short_pkt->data;
1747
1748                 }
1749
1750                 if (dlci == 0) {
1751                         MUX_TS0710_DEBUG(self->mux_id, "UIH on serv_channel 0\n");
1752                         process_mcc(data, len, ts0710,
1753                                     !(short_pkt->h.length.ea));
1754                 } else if (valid_dlci(dlci)) {
1755                         /* do line dispatch */
1756                         __u8 line;
1757                         mux_recv_struct *recv_info;
1758
1759                         mux_recv_packet *recv_packet, *recv_packet2;
1760                         MUX_TS0710_DEBUG(self->mux_id, "UIH on channel %d\n", dlci);
1761
1762                         if (uih_len > ts0710->dlci[dlci].mtu) {
1763                                 MUX_TS0710_DEBUG(self->mux_id, "MUX Error:  DLCI:%d, uih_len:%d is bigger than mtu:%d, discard data!\n",
1764                                      dlci, uih_len, ts0710->dlci[dlci].mtu);
1765                                 break;
1766                         }
1767
1768                         line = dlci2line[dlci].dataline;        /* we see data and commmand as same */
1769
1770                         if (self->callback[line].func) {
1771                                 MUX_TS0710_DEBUG(self->mux_id, "MUX: callback on mux%d", line);
1772                                 if (!(*self->callback[line].func)(line, SPRDMUX_EVENT_COMPLETE_READ, uih_data_start, uih_len, self->callback[line].user_data)) {
1773                                         break;
1774                                 }
1775                         }
1776
1777                         if ((!self->open_count[line])) {
1778                                 MUX_TS0710_DEBUG(self->mux_id, "MUX: No application waiting for, discard it! /dev/mux%d\n", line);
1779                         } else {        /* Begin processing received data */
1780                                 if ((!self->mux_recv_info_flags[line])
1781                                         || (!self->mux_recv_info[line])) {
1782                                         MUX_TS0710_DEBUG(self->mux_id, "MUX Error: No mux_recv_info, discard it! /dev/mux%d\n", line);
1783                                         break;
1784                                 }
1785
1786                                 recv_info = self->mux_recv_info[line];
1787                                 if(!recv_info) {
1788                                         MUX_TS0710_DEBUG(self->mux_id, "recv_data : recv_info is null\n");
1789                                         break;
1790                                 }
1791
1792                                 if (recv_info->total > TS0710MUX_MAX_TOTAL_SIZE) {
1793                                         MUX_TS0710_DEBUG(self->mux_id, KERN_INFO "MUX : discard data for line:%d, recv_info->total = %d!\n", line, recv_info->total);
1794                                         break;
1795                                 }
1796
1797                                 if (line <= MUX_RIL_LINE_END) {
1798                                         /* Just display AT line */
1799                                         printk(KERN_ERR "MUX: id[%d] line[%d] received %d data\n", self->mux_id, line, uih_len);
1800                                 }
1801
1802                                 mutex_lock(&recv_info->recv_data_lock);
1803
1804                                 if (recv_info->total != 0 || recv_info->length != 0) { /* add new data to tail */
1805                                         /* recv_info is already linked into mux_recv_queue */
1806                                         recv_packet = get_mux_recv_packet(uih_len);
1807                                         if (!recv_packet) {
1808                                                 MUX_TS0710_DEBUG(self->mux_id, "MUX: no memory\n");
1809                                                 mutex_unlock(&recv_info->recv_data_lock);
1810                                                 break;
1811                                         }
1812
1813                                         memcpy(recv_packet->data, uih_data_start, uih_len);
1814                                         recv_packet->length = uih_len;
1815                                         recv_info->total += uih_len;
1816                                         self->check_read_sum[line] += uih_len;
1817
1818                                         recv_packet->next = NULL;
1819
1820                                         if (!(recv_info->mux_packet)) {
1821                                                 recv_info->mux_packet = recv_packet;
1822                                         } else {
1823                                                 recv_packet2 = recv_info->mux_packet;
1824                                                 while (recv_packet2->next) {
1825                                                         recv_packet2 = recv_packet2->next;
1826                                                 }
1827                                                 recv_packet2->next = recv_packet;
1828                                         }       /* End if( !(recv_info->mux_packet) ) */
1829                                 } else {
1830                                         if (uih_len > TS0710MUX_RECV_BUF_SIZE) {
1831                                                 MUX_TS0710_DEBUG(self->mux_id, "MUX Error:  line:%d, uih_len == %d is too big\n", line, uih_len);
1832                                                 uih_len = TS0710MUX_RECV_BUF_SIZE;
1833                                         }
1834                                         memcpy(recv_info->data, uih_data_start, uih_len);
1835                                         recv_info->length = uih_len;
1836                                         recv_info->total = uih_len;
1837                                         recv_info->pos = 0;
1838                                         self->check_read_sum[line] += uih_len;
1839                                         wake_up_interruptible(&recv_info->rx_wait);
1840                                 }
1841
1842                                 mutex_unlock(&recv_info->recv_data_lock);
1843                         }       /* End processing received data */
1844                 } else {
1845                         MUX_TS0710_DEBUG(self->mux_id, "invalid dlci %d\n", dlci);
1846                 }
1847
1848                 break;
1849
1850         default:
1851                 MUX_TS0710_DEBUG(self->mux_id, "illegal packet\n");
1852                 break;
1853         }
1854         return 0;
1855 }
1856
1857 /* Close ts0710 channel */
1858 static void ts0710_close_channel(ts0710_con *ts0710, __u8 dlci)
1859 {
1860         int try;
1861         unsigned long t;
1862         struct sprd_mux *self = NULL;
1863
1864         if (!ts0710) {
1865                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
1866                 return;
1867         }
1868
1869         self = (struct sprd_mux *)ts0710->user_data;
1870
1871         if (!self) {
1872                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
1873                 return;
1874         }
1875
1876         MUX_TS0710_DEBUG(((struct sprd_mux *)ts0710->user_data)->mux_id, "ts0710_disc_command on channel %d\n", dlci);
1877
1878         if ((ts0710->dlci[dlci].state == DISCONNECTED)
1879             || (ts0710->dlci[dlci].state == REJECTED)) {
1880                 return;
1881         } else if (ts0710->dlci[dlci].state == DISCONNECTING) {
1882                 /* Reentry */
1883                 return;
1884         } else {
1885                 ts0710->dlci[dlci].state = DISCONNECTING;
1886                 if (self->mux_status != MUX_STATE_READY) {
1887                         printk(KERN_ERR "MUX: Error %s cp is Not OK\n", __FUNCTION__);
1888                         ts0710->dlci[dlci].state = DISCONNECTED;
1889                         return;
1890                 }
1891
1892                 try = 1;
1893                 while (try) {
1894                         --try;
1895                         t = jiffies;
1896                         send_disc(ts0710, dlci);
1897                         interruptible_sleep_on_timeout(&ts0710->dlci[dlci].close_wait, 10 * TS0710MUX_TIME_OUT);
1898
1899                         if (ts0710->dlci[dlci].state == DISCONNECTED) {
1900                                 break;
1901                         } else if (ts0710->dlci[dlci].state == CONNECTED || ts0710->dlci[dlci].state == CONNECTING) {
1902                                 /* Todo:Should NOT be here */
1903                                 printk(KERN_ERR "MUX id[%d] DLCI:%d opening occured!\n", self->mux_id, dlci);
1904                                 break;
1905                         }
1906                         else if (signal_pending(current)) {
1907                                 MUX_TS0710_DEBUG(((struct sprd_mux *)ts0710->user_data)->mux_id, "MUX DLCI %d Send DISC got signal!\n", dlci);
1908                                 break;
1909                         } else if ((jiffies - t) >= TS0710MUX_TIME_OUT) {
1910                                 MUX_TS0710_DEBUG(((struct sprd_mux *)ts0710->user_data)->mux_id, "MUX DLCI %d Send DISC timeout!\n", dlci);
1911                                 break;
1912                         }
1913                 }
1914                 if (ts0710->dlci[dlci].state != DISCONNECTED) {
1915                         if (dlci == 0) {        /* Control Channel */
1916                                 ts0710_upon_disconnect(ts0710);
1917                         } else {        /* Other Channel */
1918                                 ts0710->dlci[dlci].state = DISCONNECTED;
1919                                 wake_up_interruptible(&ts0710->dlci[dlci].close_wait);
1920                                 ts0710_reset_dlci(ts0710, dlci);
1921                         }
1922                 }
1923         }
1924 }
1925
1926 static int ts0710_open_channel(ts0710_con *ts0710, __u8 dlci)
1927 {
1928         int try;
1929         int retval;
1930         struct sprd_mux *self = NULL;
1931
1932         retval = -ENODEV;
1933
1934         if (!ts0710) {
1935                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
1936                 return retval;
1937         }
1938
1939         self = (struct sprd_mux *)ts0710->user_data;
1940
1941         if (!self) {
1942                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
1943                 return retval;
1944         }
1945
1946         TS0710_PRINTK("MUX %s id[%d] DLCI:%d state = %d dlci[0]'state = %d\n", __FUNCTION__, self->mux_id, dlci, ts0710->dlci[dlci].state, ts0710->dlci[0].state);
1947
1948         if (dlci == 0) {        /* control channel */
1949                 if ((ts0710->dlci[0].state == CONNECTED)
1950                     || (ts0710->dlci[0].state == FLOW_STOPPED)) {
1951                         return 0;
1952                 } else if (ts0710->dlci[0].state == CONNECTING) {
1953                         /* Reentry */
1954                         printk(KERN_INFO "MUX: id[%d] DLCI: 0, reentry to open DLCI 0, pid: %d, %s !\n",self->mux_id, current->pid, current->comm);
1955                         try = 1;/* No try*/
1956                         while (try) {
1957                                 --try;
1958                                 wait_event_interruptible(ts0710->dlci[0].open_wait, ts0710->dlci[0].state != CONNECTING || self->mux_status == MUX_STATE_CRASHED);
1959                                 TS0710_PRINTK("MUX: id[%d] DLCI:%d after open wait state = %d try = %d", self->mux_id, dlci, ts0710->dlci[dlci].state, try);
1960
1961                                 if (self->mux_status == MUX_STATE_CRASHED) {
1962                                         printk(KERN_INFO "MUX: id[%d] Error DLCI[%d] cp is crashed!\n", self->mux_id, dlci);
1963                                 //Need check
1964                                         return -ENODEV;
1965                                 }
1966
1967                                 if ((ts0710->dlci[0].state == CONNECTED)
1968                                     || (ts0710->dlci[0].state == FLOW_STOPPED)) {
1969                                         retval = 0;
1970                                         break;
1971                                 } else if (ts0710->dlci[0].state == REJECTED) {
1972                                         printk(KERN_ERR "MUX: id[%d] Error DLCI[%d] REJECTED\n", self->mux_id, dlci);
1973                                         retval = -EREJECTED;
1974                                         break;
1975                                 } else if (ts0710->dlci[0].state == DISCONNECTED) {
1976                                         printk(KERN_ERR "MUX: id[%d] Error DLCI[%d] DISCONNECTED\n", self->mux_id, dlci);
1977                                         retval = -EAGAIN;
1978                                         break;
1979                                 } else if (signal_pending(current)) {
1980                                         printk(KERN_ERR "MUX: id[%d] DLCI:%d Wait for connecting got signal!\n", self->mux_id, dlci);
1981                                         retval = -EAGAIN;
1982                                         break;
1983
1984                                 } else if (ts0710->dlci[0].state == CONNECTING) {
1985                                         printk(KERN_ERR "MUX: id[%d] DLCI:%d error out 6\n", self->mux_id, dlci);
1986                                         break;
1987                                 }
1988                         }
1989
1990                         if (ts0710->dlci[0].state == CONNECTING) {
1991                                 ts0710->dlci[0].state = DISCONNECTED;
1992                                 retval = -EAGAIN;
1993                         }
1994                 } else if ((ts0710->dlci[0].state != DISCONNECTED)
1995                            && (ts0710->dlci[0].state != REJECTED)) {
1996                         printk(KERN_ERR "MUX: id[%d] DLCI:%d state is invalid!\n", self->mux_id, dlci);
1997                         return retval;
1998                 } else {
1999                         ts0710->initiator = 1;
2000                         ts0710->dlci[0].state = CONNECTING;
2001                         ts0710->dlci[0].initiator = 1;
2002                         try = 1;/* No try*/
2003                         while (try) {
2004
2005                                 --try;
2006                                 send_sabm(ts0710, 0);
2007                                 wait_event_interruptible(ts0710->dlci[0].open_wait, ts0710->dlci[0].state != CONNECTING || self->mux_status == MUX_STATE_CRASHED);
2008
2009                                 TS0710_PRINTK("MUX: id[%d] DLCI:%d after open wait state = %d try = %d", self->mux_id, dlci, ts0710->dlci[dlci].state, try);
2010
2011                                 if (self->mux_status == MUX_STATE_CRASHED) {
2012                                         printk(KERN_INFO "MUX: id[%d] Error DLCI[%d] cp is crashed!\n", self->mux_id, dlci);
2013                                 //Need check
2014                                         return -ENODEV;
2015                                 }
2016
2017                                 if ((ts0710->dlci[0].state == CONNECTED)
2018                                     || (ts0710->dlci[0].state == FLOW_STOPPED)) {
2019                                         retval = 0;
2020                                         break;
2021                                 } else if (ts0710->dlci[0].state == REJECTED) {
2022                                         printk(KERN_ERR "MUX: id[%d] DLCI:%d Send SABM got rejected!\n",self->mux_id, dlci);
2023                                         retval = -EREJECTED;
2024                                         break;
2025                                 } else if (signal_pending(current)) {
2026                                         printk(KERN_ERR "MUX: id[%d] DLCI:%d Send SABM got signal!\n", self->mux_id, dlci);
2027                                         retval = -EAGAIN;
2028                                         break;
2029                                 }
2030                         }
2031
2032                         if (ts0710->dlci[0].state == CONNECTING) {
2033                                 ts0710->dlci[0].state = DISCONNECTED;
2034                                 retval = -EAGAIN;
2035                         }
2036                         wake_up_all(&ts0710->dlci[0].open_wait);
2037                 }
2038         } else {        /* other channel */
2039                 if ((ts0710->dlci[0].state != CONNECTED)
2040                     && (ts0710->dlci[0].state != FLOW_STOPPED)) {
2041                         return retval;
2042                 } else if ((ts0710->dlci[dlci].state == CONNECTED)
2043                            || (ts0710->dlci[dlci].state == FLOW_STOPPED)) {
2044                         return 0;
2045                 } else if ((ts0710->dlci[dlci].state == NEGOTIATING)
2046                            || (ts0710->dlci[dlci].state == CONNECTING)) {
2047                         /* Reentry */
2048                         try = 1;/* No try*/
2049                         while (try) {
2050
2051                                 --try;
2052                                 wait_event_interruptible(ts0710->dlci[dlci].open_wait, (ts0710->dlci[dlci].state != CONNECTING || ts0710->dlci[dlci].state!= NEGOTIATING || self->mux_status == MUX_STATE_CRASHED));
2053                                 TS0710_PRINTK("MUX: id[%d] DLCI:%d after open wait state = %d try = %d", self->mux_id, dlci, ts0710->dlci[dlci].state, try);
2054
2055                                 if (self->mux_status == MUX_STATE_CRASHED) {
2056                                         printk(KERN_INFO "MUX: id[%d] Error DLCI[%d] cp is crashed!\n", self->mux_id, dlci);
2057                                 //Need check
2058                                         return -ENODEV;
2059                                 }
2060
2061                                 if ((ts0710->dlci[dlci].state == CONNECTED)
2062                                     || (ts0710->dlci[dlci].state == FLOW_STOPPED)) {
2063                                         retval = 0;
2064                                         break;
2065                                 } else if (ts0710->dlci[dlci].state == REJECTED) {
2066                                         retval = -EREJECTED;
2067                                         printk(KERN_ERR "MUX: id[%d] DLCI:%d Send SABM got rejected!\n",self->mux_id, dlci);
2068                                         break;
2069                                 } else if (ts0710->dlci[dlci].state == DISCONNECTED) {
2070                                         printk(KERN_ERR "MUX: id[%d] Error DLCI[%d] DISCONNECTED\n", self->mux_id, dlci);
2071                                         break;
2072                                 } else if (signal_pending(current)) {
2073                                         printk(KERN_ERR "MUX: id[%d] DLCI:%d Wait for connecting got signal!\n", self->mux_id, dlci);
2074                                         retval = -EAGAIN;
2075                                         break;
2076                                 } else if ((ts0710->dlci[dlci].state == NEGOTIATING)
2077                                         || (ts0710->dlci[dlci].state == CONNECTING)) {
2078                                         printk(KERN_ERR "MUX: id[%d] DLCI:%d CONNECTING or NEGOTIATING\n", self->mux_id, dlci);
2079                                         break;
2080                                 }
2081                         }
2082
2083                         if ((ts0710->dlci[dlci].state == NEGOTIATING)
2084                             || (ts0710->dlci[dlci].state == CONNECTING)) {
2085                                 ts0710->dlci[dlci].state = DISCONNECTED;
2086                                 retval = -EAGAIN;
2087                         }
2088                 } else if ((ts0710->dlci[dlci].state != DISCONNECTED)
2089                            && (ts0710->dlci[dlci].state != REJECTED)) {
2090                         return retval;
2091                 } else {
2092                         ts0710->dlci[dlci].state = CONNECTING;
2093                         ts0710->dlci[dlci].initiator = 1;
2094                         if (ts0710->dlci[dlci].state == CONNECTING) {
2095                                 try = 1;
2096                                 while (try) {
2097
2098                                         --try;
2099                                         send_sabm(ts0710, dlci);
2100                                         wait_event_interruptible(ts0710->dlci[dlci].open_wait,ts0710->dlci[dlci].state != CONNECTING || self->mux_status == MUX_STATE_CRASHED);
2101
2102                                         TS0710_PRINTK("MUX: id[%d] DLCI:%d after open wait state = %d try = %d", self->mux_id, dlci, ts0710->dlci[dlci].state, try);
2103
2104                                         if (self->mux_status == MUX_STATE_CRASHED) {
2105                                                 printk(KERN_INFO "MUX: id[%d] Error DLCI[%d] cp is crashed!\n", self->mux_id, dlci);
2106                                                 //Need check
2107                                                 return -ENODEV;
2108                                         }
2109
2110                                         if ((ts0710->dlci[dlci].state == CONNECTED)
2111                                             || (ts0710->dlci[dlci].state ==FLOW_STOPPED)) {
2112                                                 retval = 0;
2113                                                 break;
2114                                         } else if (ts0710->dlci[dlci].state == DISCONNECTED || ts0710->dlci[dlci].state == DISCONNECTING) {
2115                                                 /* Todo:Should NOT be here */
2116                                                 printk(KERN_ERR "MUX id[%d] DLCI:%d opening occured!\n", self->mux_id, dlci);
2117                                                 retval = -EAGAIN;
2118                                                 break;
2119                                         } else if (ts0710->dlci[dlci].state == REJECTED) {
2120                                                 printk(KERN_ERR "MUX: id[%d] DLCI:%d Send SABM got rejected!\n", self->mux_id, dlci);
2121                                                 retval = -EREJECTED;
2122                                                 break;
2123                                         } else if (signal_pending(current)) {
2124                                                 printk(KERN_ERR "MUX: id[%d] DLCI:%d Send SABM got signal!\n", self->mux_id, dlci);
2125                                                 retval = -EAGAIN;
2126                                                 break;
2127                                         }
2128                                 }
2129                         }
2130
2131                         if ((ts0710->dlci[dlci].state == NEGOTIATING)
2132                             || (ts0710->dlci[dlci].state == CONNECTING)) {
2133                                 ts0710->dlci[dlci].state = DISCONNECTED;
2134                                 retval = -EAGAIN;
2135                         }
2136                         wake_up_all(&ts0710->dlci[dlci].open_wait);
2137                 }
2138         }
2139         return retval;
2140 }
2141
2142 static int ts0710_exec_test_cmd(ts0710_con *ts0710)
2143 {
2144         __u8 *f_buf;            /* Frame buffer */
2145         __u8 *d_buf;            /* Data buffer */
2146         int retval = -EFAULT;
2147         int j;
2148         unsigned long t;
2149         struct sprd_mux *self = NULL;
2150
2151         if (!ts0710) {
2152                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
2153                 return retval;
2154         }
2155
2156         self = (struct sprd_mux *)ts0710->user_data;
2157
2158         if (!self) {
2159                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
2160                 return retval;
2161         }
2162
2163         MUX_TS0710_DEBUG(self->mux_id, "ts0710_exec_test_cmd\n");
2164
2165         if (ts0710->be_testing) {
2166                 /* Reentry */
2167                 t = jiffies;
2168                 interruptible_sleep_on_timeout(&ts0710->test_wait,
2169                                                3 * TS0710MUX_TIME_OUT);
2170                 if (ts0710->be_testing == 0) {
2171                         if (ts0710->test_errs == 0) {
2172                                 retval = 0;
2173                         } else {
2174                                 retval = -EFAULT;
2175                         }
2176                 } else if (signal_pending(current)) {
2177                         MUX_TS0710_DEBUG(self->mux_id, "Wait for Test_cmd response got signal!\n");
2178                         retval = -EAGAIN;
2179                 } else if ((jiffies - t) >= 3 * TS0710MUX_TIME_OUT) {
2180                         MUX_TS0710_DEBUG(self->mux_id, "Wait for Test_cmd response timeout!\n");
2181                         retval = -EFAULT;
2182                 }
2183         } else {
2184                 ts0710->be_testing = 1; /* Set the flag */
2185
2186                 f_buf = (__u8 *) kmalloc(TEST_PATTERN_SIZE + 32, GFP_KERNEL);
2187                 d_buf = (__u8 *) kmalloc(TEST_PATTERN_SIZE + 32, GFP_KERNEL);
2188                 if ((!f_buf) || (!d_buf)) {
2189                         if (f_buf) {
2190                                 kfree(f_buf);
2191                         }
2192                         if (d_buf) {
2193                                 kfree(d_buf);
2194                         }
2195
2196                         ts0710->be_testing = 0; /* Clear the flag */
2197                         ts0710->test_errs = TEST_PATTERN_SIZE;
2198                         wake_up_interruptible(&ts0710->test_wait);
2199                         return -ENOMEM;
2200                 }
2201
2202                 for (j = 0; j < TEST_PATTERN_SIZE; j++) {
2203                         d_buf[j] = j & 0xFF;
2204                 }
2205
2206                 t = jiffies;
2207                 ts0710_test_msg(ts0710, d_buf, TEST_PATTERN_SIZE, MCC_CMD,
2208                                 f_buf);
2209                 interruptible_sleep_on_timeout(&ts0710->test_wait,
2210                                                2 * TS0710MUX_TIME_OUT);
2211                 if (ts0710->be_testing == 0) {
2212                         if (ts0710->test_errs == 0) {
2213                                 retval = 0;
2214                         } else {
2215                                 retval = -EFAULT;
2216                         }
2217                 } else if (signal_pending(current)) {
2218                         MUX_TS0710_DEBUG(self->mux_id, "Send Test_cmd got signal!\n");
2219                         retval = -EAGAIN;
2220                 } else if ((jiffies - t) >= 2 * TS0710MUX_TIME_OUT) {
2221                         MUX_TS0710_DEBUG(self->mux_id, "Send Test_cmd timeout!\n");
2222                         ts0710->test_errs = TEST_PATTERN_SIZE;
2223                         retval = -EFAULT;
2224                 }
2225
2226                 ts0710->be_testing = 0; /* Clear the flag */
2227                 wake_up_interruptible(&ts0710->test_wait);
2228
2229                 /* Release buffer */
2230                 if (f_buf) {
2231                         kfree(f_buf);
2232                 }
2233                 if (d_buf) {
2234                         kfree(d_buf);
2235                 }
2236         }
2237
2238         return retval;
2239 }
2240
2241 static void mux_sched_send(struct sprd_mux *self)
2242 {
2243         if (!self) {
2244                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
2245                 return;
2246         }
2247
2248         complete(&self->send_completion);
2249 }
2250
2251 /*
2252  * Returns 1 if found, 0 otherwise. needle must be null-terminated.
2253  * strstr might not work because WebBox sends garbage before the first OKread
2254  *
2255  */
2256 int findInBuf(unsigned char *buf, int len, char *needle)
2257 {
2258         int i;
2259         int needleMatchedPos = 0;
2260
2261         if (needle[0] == '\0') {
2262                 return 1;
2263         }
2264
2265         for (i = 0; i < len; i++) {
2266                 if (needle[needleMatchedPos] == buf[i]) {
2267                         needleMatchedPos++;
2268                         if (needle[needleMatchedPos] == '\0') {
2269                                 /* Entire needle was found */
2270                                 return 1;
2271                         }
2272                 } else {
2273                         needleMatchedPos = 0;
2274                 }
2275         }
2276         return 0;
2277 }
2278
2279
2280 /****************************
2281  * TTY driver routines
2282 *****************************/
2283 void ts0710_mux_close(int mux_id, int line)
2284 {
2285         __u8 dlci;
2286         __u8 cmdline;
2287         __u8 dataline;
2288         ts0710_con *ts0710 = NULL;
2289         struct sprd_mux *self = NULL;
2290
2291         if ((line < 0) || (line >= NR_MUXS)) {
2292                 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] is invalid\n", __FUNCTION__, mux_id, line);
2293                 return;
2294         }
2295
2296         self = sprd_mux_mgr[mux_id].handle;
2297
2298         if (!self) {
2299                 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] self is NULL\n", __FUNCTION__, mux_id, line);
2300                 return;
2301         }
2302
2303         ts0710 = self ->connection;
2304         if (!ts0710) {
2305                 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] ts0710 is NULL\n", __FUNCTION__, mux_id, line);
2306                 return;
2307         }
2308
2309         if (self->open_count[line] > 0) {
2310                 self->open_count[line]--;
2311         }
2312
2313         // The close here and the open in mux_recover_thread may conflict, so wait
2314         if (self->mux_status == MUX_STATE_RECOVERING) {
2315                 int rval = 0;
2316
2317                 printk(KERN_INFO "MUX: mux[%d] line[%d] pid[%d] wait close \n", mux_id, line, current->pid);
2318
2319                 rval = wait_event_interruptible_timeout(self->modem_ready, self->mux_status == MUX_STATE_READY, TS0710MUX_TIME_OUT);
2320
2321                 if (rval < 0) {
2322                         printk(KERN_WARNING "MUX: %s mux[%d] line[%d] pid[%d] close wait interrupted!\n", __FUNCTION__, mux_id, line, current->pid);
2323                 
2324                 } else if (rval == 0) {
2325                         printk(KERN_WARNING "MUX: %s mux[%d] line[%d] pid[%d] timeout!\n", __FUNCTION__, mux_id, line, current->pid);
2326                 
2327                 }
2328         }
2329
2330         printk(KERN_INFO "MUX: mux[%d] line[%d] pid[%d] closed!\n", mux_id, line, current->pid);
2331
2332         dlci = line2dlci[line];
2333         cmdline = dlci2line[dlci].cmdline;
2334         dataline = dlci2line[dlci].dataline;
2335
2336         if ((self->open_count[cmdline] == 0) && (self->open_count[dataline] == 0)) {
2337                 //close current channel first
2338                 ts0710_close_channel(ts0710, dlci);
2339         }
2340
2341         if (self->open_count[line] == 0) {
2342                 if ((self->mux_send_info_flags[line])
2343                         && (self->mux_send_info[line])
2344                         ) {
2345                         self->mux_send_info_flags[line] = 0;
2346                         mux_free_send_info(self->mux_send_info[line]);
2347                         self->mux_send_info[line] = 0;
2348                         MUX_TS0710_DEBUG(self->mux_id, "Free mux_send_info for /dev/mux%d\n", line);
2349                 }
2350
2351                 if ((self->mux_recv_info_flags[line])
2352                         && (self->mux_recv_info[line])
2353                         && (self->mux_recv_info[line]->total == 0)) {
2354                         self->mux_recv_info_flags[line] = 0;
2355                         free_mux_recv_struct(self->mux_recv_info[line]);
2356                         self->mux_recv_info[line] = 0;
2357                         MUX_TS0710_DEBUG(self->mux_id, "Free mux_recv_info for /dev/mux%d\n", line);
2358                 }
2359         }
2360 }
2361
2362 int ts0710_mux_read(int mux_id, int line, const unsigned char *buf, int count, int timeout)
2363 {
2364         __u8 dlci;
2365         mux_recv_struct *recv_info;
2366         struct sprd_mux *self = NULL;
2367         ts0710_con *ts0710 = NULL;
2368         int rval = 0;
2369         mux_recv_packet *recv_packet;
2370         unsigned char *buf_pos;
2371         int cp_cnt = 0;
2372
2373         MUX_TS0710_DEBUG(mux_id, "line[%d] pid[%d] count  = %d, timeout = %d\n", line, current->pid, count, timeout);
2374
2375         if (count <= 0) {
2376                 return 0;
2377         }
2378
2379         if ((line < 0) || (line >= NR_MUXS)) {
2380                 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] is invalid\n", __FUNCTION__, mux_id, line);
2381                 return -EINVAL;
2382         }
2383
2384         self = sprd_mux_mgr[mux_id].handle;
2385
2386         if (!self) {
2387                 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] self is NULL\n", __FUNCTION__, mux_id, line);
2388                 return -ENODEV;
2389         }
2390
2391         ts0710 = self ->connection;
2392         if (!ts0710) {
2393                 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] ts0710 is NULL\n", __FUNCTION__, mux_id, line);
2394                 return -ENODEV;
2395         }
2396
2397         dlci = line2dlci[line];
2398         if (ts0710->dlci[0].state == FLOW_STOPPED) {
2399                 MUX_TS0710_DEBUG(self->mux_id, "Flow stopped on all channels, returning zero /dev/mux%d\n", line);
2400                 return 0;
2401         } else if (ts0710->dlci[dlci].state == FLOW_STOPPED) {
2402                 MUX_TS0710_DEBUG(self->mux_id, "Flow stopped, returning zero /dev/mux%d\n", line);
2403                 return 0;
2404         } else if (ts0710->dlci[dlci].state == CONNECTED) {
2405                 if (!(self->mux_send_info_flags[line])) {
2406                         TS0710_PRINTK("MUX Error: mux_write: mux_send_info_flags[%d] == 0\n", line);
2407                         return -ENODEV;
2408                 }
2409                 recv_info = self->mux_recv_info[line];
2410                 if (!recv_info) {
2411                         TS0710_PRINTK("MUX Error: mux_write: mux_send_info[%d] == 0\n", line);
2412                         return -ENODEV;
2413                 }
2414
2415                 if (timeout == 0) {
2416                         if (!mutex_trylock(&recv_info->recv_lock)) {
2417                                 printk(KERN_INFO "MUX: %s mux[%d] line[%d] pid[%d] is busy!\n", __FUNCTION__, mux_id, line, current->pid);
2418                                 return -EBUSY;
2419                         }
2420
2421                         if (recv_info->total == 0) {
2422                                 printk(KERN_INFO "MUX: %s mux[%d] line[%d] pid[%d] is empty!\n", __FUNCTION__, mux_id, line, current->pid);
2423                                 mutex_unlock(&recv_info->recv_lock);
2424                                 return -EBUSY;
2425                         }
2426                 } else if (timeout < 0){
2427                         mutex_lock(&recv_info->recv_lock);
2428                         MUX_TS0710_DEBUG(mux_id, "line[%d] pid[%d] read wait\n", line, current->pid);
2429                         rval = wait_event_interruptible(recv_info->rx_wait, recv_info->total != 0 && self->mux_status == MUX_STATE_READY);
2430                         if (rval < 0) {
2431                                 printk(KERN_WARNING "MUX: %s mux[%d] line[%d] pid[%d] read wait interrupted!\n", __FUNCTION__, mux_id, line, current->pid);
2432                                 mutex_unlock(&recv_info->recv_lock);
2433                                 return -EINTR;
2434                         }
2435                 }else {
2436                         mutex_lock(&recv_info->recv_lock);
2437                         rval = wait_event_interruptible_timeout(recv_info->rx_wait, recv_info->total != 0 && self->mux_status == MUX_STATE_READY, timeout);
2438                         if (rval < 0) {
2439                                 printk(KERN_WARNING "MUX: %s mux[%d] line[%d] pid[%d] write wait interrupted!\n", __FUNCTION__, mux_id, line, current->pid);
2440                                 mutex_unlock(&recv_info->recv_lock);
2441                                 return -EINTR;
2442
2443                         } else if (rval == 0) {
2444                                 printk(KERN_WARNING "MUX: %s mux[%d] line[%d] pid[%d] timeout!\n", __FUNCTION__, mux_id, line, current->pid);
2445                                 mutex_unlock(&recv_info->recv_lock);
2446                                 return -ETIME;
2447
2448                         }
2449                 }
2450
2451                 mutex_lock(&recv_info->recv_data_lock);
2452
2453                 buf_pos = (unsigned char *)buf;
2454
2455                 MUX_TS0710_DEBUG(mux_id, "line[%d] pid[%d] length  = %d total = %d\n", line, current->pid, recv_info->length, recv_info->total);
2456
2457                 //copy data of recv_info before one of the packet
2458                 if (recv_info->length != 0) {
2459
2460                         cp_cnt = min(count, recv_info->length);
2461
2462                         if ((uint32_t)buf > TASK_SIZE) {
2463                                 memcpy(buf_pos, recv_info->data + recv_info->pos, cp_cnt);
2464                         } else {
2465                                 if(copy_to_user(buf_pos, recv_info->data + recv_info->pos, cp_cnt)) {
2466                                         mutex_unlock(&recv_info->recv_data_lock);
2467                                         mutex_unlock(&recv_info->recv_lock);
2468                                         return -EFAULT;
2469                                 }
2470                         }
2471
2472                         buf_pos += cp_cnt;
2473                         count -= cp_cnt;
2474                         recv_info->length -= cp_cnt;
2475                         recv_info->total -= cp_cnt;
2476
2477                         self->check_read_sum[line] -= cp_cnt;
2478
2479                         if (recv_info->length == 0) {
2480                                 recv_info->pos = 0;
2481                         } else {
2482                                 recv_info->pos += cp_cnt;
2483                         }
2484                 }
2485
2486                 while(count > 0 && recv_info->total != 0) {
2487                         if ((recv_packet = recv_info->mux_packet)) {
2488                                 cp_cnt = min(count, recv_packet->length);
2489
2490                                 if ((uint32_t)buf > TASK_SIZE) {
2491                                         memcpy(buf_pos, recv_packet->data + recv_packet->pos, cp_cnt);
2492                                 } else {
2493                                         if(copy_to_user(buf_pos, recv_packet->data + recv_packet->pos, cp_cnt)) {
2494                                                 mutex_unlock(&recv_info->recv_data_lock);
2495                                                 mutex_unlock(&recv_info->recv_lock);
2496                                                 printk(KERN_ERR "MUX: %s mux[%d] line[%d] pid[%d] total is error!\n", __FUNCTION__, mux_id, line, current->pid);
2497                                                 return -EFAULT;
2498                                         }
2499                                 }
2500
2501                                 buf_pos += cp_cnt;
2502                                 count -= cp_cnt;
2503                                 recv_packet->length -= cp_cnt;
2504                                 recv_info->total -= cp_cnt;
2505                                 self->check_read_sum[line] -= cp_cnt;
2506
2507                                 if (recv_packet->length == 0) {
2508                                         recv_packet->pos = 0;
2509                                         recv_info->mux_packet = recv_packet->next;
2510                                         free_mux_recv_packet(recv_packet);
2511                                 } else {
2512                                         recv_packet->pos += cp_cnt;
2513                                 }
2514                         } else {
2515                                 if (recv_info->total != 0) {
2516                                         printk(KERN_ERR "MUX: %s mux[%d] line[%d] pid[%d] total is incorrect!\n", __FUNCTION__, mux_id, line, current->pid);
2517                                         break;
2518                                 }
2519                         }
2520                 }
2521                 mutex_unlock(&recv_info->recv_data_lock);
2522                 mutex_unlock(&recv_info->recv_lock);
2523
2524                 MUX_TS0710_DEBUG(mux_id, "line[%d] pid[%d] read = %d\n", line, current->pid, buf_pos - buf);
2525
2526                 return buf_pos - buf;
2527         }
2528         return 0;
2529 }
2530
2531 int ts0710_mux_poll_wait(int mux_id, int line, struct file *filp, poll_table *wait)
2532 {
2533         __u8 dlci;
2534         struct sprd_mux *self = NULL;
2535         ts0710_con *ts0710 = NULL;
2536         mux_send_struct *send_info;
2537         mux_recv_struct *recv_info;
2538         unsigned int mask = 0;
2539
2540         if ((line < 0) || (line >= NR_MUXS)) {
2541                 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] is invalid\n", __FUNCTION__, mux_id, line);
2542                 return -EINVAL;
2543         }
2544
2545         self = sprd_mux_mgr[mux_id].handle;
2546         if (!self) {
2547                 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] self is NULL\n", __FUNCTION__, mux_id, line);
2548                 return -ENODEV;
2549         }
2550
2551         ts0710 = self ->connection;
2552         if (!ts0710) {
2553                 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] ts0710 is NULL\n", __FUNCTION__, mux_id, line);
2554                 return -ENODEV;
2555         }
2556
2557         dlci = line2dlci[line];
2558         if (ts0710->dlci[dlci].state != CONNECTED) {
2559                 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] state is %d\n", __FUNCTION__, mux_id, line, ts0710->dlci[dlci].state);
2560                 return -ENODEV;
2561         }
2562
2563         send_info = self->mux_send_info[line];
2564         recv_info = self->mux_recv_info[line];
2565
2566         poll_wait(filp, &send_info->tx_wait, wait);
2567         poll_wait(filp, &recv_info->rx_wait, wait);
2568
2569         if (recv_info->total != 0 && self->mux_status == MUX_STATE_READY) {
2570                 mask |= POLLIN | POLLRDNORM;
2571         }
2572
2573         if (mux_line_state(mux_id, line) == 0 && self->mux_status == MUX_STATE_READY) {
2574                 mask |= POLLOUT | POLLWRNORM;
2575         }
2576
2577         return mask;
2578
2579 }
2580
2581 int ts0710_mux_write(int mux_id, int line, const unsigned char *buf, int count, int timeout)
2582 {
2583         __u8 dlci;
2584         mux_send_struct *send_info;
2585         __u8 *d_buf;
2586         __u16 c;
2587         struct sprd_mux *self = NULL;
2588         ts0710_con *ts0710 = NULL;
2589         int rval = 0;
2590         __u32 ring_index;
2591
2592         MUX_TS0710_DEBUG(mux_id, "line[%d] pid[%d] count  = %d, timeout = %d\n", line, current->pid, count, timeout);
2593
2594         if (count <= 0) {
2595                 return 0;
2596         }
2597
2598         if ((line < 0) || (line >= NR_MUXS)) {
2599                 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] is invalid\n", __FUNCTION__, mux_id, line);
2600                 return -EINVAL;
2601         }
2602
2603         self = sprd_mux_mgr[mux_id].handle;
2604
2605         if (!self) {
2606                 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] self is NULL\n", __FUNCTION__, mux_id, line);
2607                 return -ENODEV;
2608         }
2609
2610         ts0710 = self ->connection;
2611         if (!ts0710) {
2612                 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] ts0710 is NULL\n", __FUNCTION__, mux_id, line);
2613                 return -ENODEV;
2614         }
2615
2616         dlci = line2dlci[line];
2617         if (ts0710->dlci[0].state == FLOW_STOPPED) {
2618                 MUX_TS0710_DEBUG(self->mux_id, "Flow stopped on all channels, returning zero /dev/mux%d\n", line);
2619                 return 0;
2620         } else if (ts0710->dlci[dlci].state == FLOW_STOPPED) {
2621                 MUX_TS0710_DEBUG(self->mux_id, "Flow stopped, returning zero /dev/mux%d\n", line);
2622                 return 0;
2623         } else if (ts0710->dlci[dlci].state == CONNECTED) {
2624                 if (!(self->mux_send_info_flags[line])) {
2625                         TS0710_PRINTK("MUX Error: mux_write: mux_send_info_flags[%d] == 0\n", line);
2626                         return -ENODEV;
2627                 }
2628                 send_info = self->mux_send_info[line];
2629                 if (!send_info) {
2630                         TS0710_PRINTK("MUX Error: mux_write: mux_send_info[%d] == 0\n", line);
2631                         return -ENODEV;
2632                 }
2633
2634                 c = min(count, (ts0710->dlci[dlci].mtu - 1));
2635
2636                 if (c <= 0) {
2637                         return 0;
2638                 }
2639
2640                 if (timeout == 0) {
2641                         if (!mutex_trylock(&send_info->send_lock)) {
2642                                 printk(KERN_INFO "MUX: %s mux[%d] line[%d] pid[%d] is busy!\n", __FUNCTION__, mux_id, line, current->pid);
2643                                 return -EBUSY;
2644                         }
2645
2646                         if (mux_line_state(mux_id, line)) {
2647                                 printk(KERN_INFO "MUX: %s mux[%d] line[%d] pid[%d] is filled!\n", __FUNCTION__, mux_id, line, current->pid);
2648                                 mutex_unlock(&send_info->send_lock);
2649                                 return -EBUSY;
2650                         }
2651
2652                         if (self->mux_status != MUX_STATE_READY)
2653                         {
2654                                 printk(KERN_INFO "MUX: %s mux[%d] line[%d] pid[%d] mux is Not ready!\n", __FUNCTION__, mux_id, line, current->pid);
2655                                 mutex_unlock(&send_info->send_lock);
2656                                 return -EBUSY;
2657                         }
2658                 } else if (timeout < 0){
2659                                 mutex_lock(&send_info->send_lock);
2660
2661                                 MUX_TS0710_DEBUG(mux_id, "line[%d] pid[%d] wait write\n", line, current->pid);
2662
2663                                 rval = wait_event_interruptible(send_info->tx_wait, mux_line_state(mux_id, line) == 0 && self->mux_status == MUX_STATE_READY);
2664                                 if (rval < 0) {
2665                                         printk(KERN_WARNING "MUX: %s mux[%d] line[%d] pid[%d] write wait interrupted!\n", __FUNCTION__, mux_id, line, current->pid);
2666                                         mutex_unlock(&send_info->send_lock);
2667                                         return -EINTR;
2668                                 }
2669                 }else {
2670                         mutex_lock(&send_info->send_lock);
2671                         rval = wait_event_interruptible_timeout(send_info->tx_wait, mux_line_state(mux_id, line) == 0 && self->mux_status == MUX_STATE_READY, timeout);
2672                         if (rval < 0) {
2673                                 printk(KERN_WARNING "MUX: %s mux[%d] line[%d] pid[%d] write wait interrupted!\n", __FUNCTION__, mux_id, line, current->pid);
2674                                 mutex_unlock(&send_info->send_lock);
2675                                 rval = -EINTR;
2676                         } else if (rval == 0) {
2677                                 printk(KERN_WARNING "MUX: %s mux[%d] line[%d] pid[%d] timeout!\n", __FUNCTION__, mux_id, line, current->pid);
2678                                 mutex_unlock(&send_info->send_lock);
2679                                 return -ETIME;
2680                         }
2681                 }
2682
2683                 ring_index = send_info->write_index % ringbuf_num[mux_id][line];
2684
2685                 d_buf = send_info->buf + (ring_index * TS0710MUX_SEND_BUF_SIZE) + TS0710MUX_SEND_BUF_OFFSET;
2686
2687 //              printk(KERN_ERR "MUX: %s mux[%d] line[%d] pid[%d]       ring_index = %d, num = %d\n", __FUNCTION__, mux_id, line, current->pid, ring_index, ringbuf_num[mux_id][line]);
2688
2689                 if ((uint32_t)buf > TASK_SIZE) {
2690                         memcpy(&d_buf[0], buf, c);
2691                 } else {
2692                         if(copy_from_user(&d_buf[0], buf, c)) {
2693                                 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] pid[%d] failed to copy from user!\n", __FUNCTION__, mux_id, line, current->pid);
2694                                 mutex_unlock(&send_info->send_lock);
2695                                 return -EFAULT;
2696                         }
2697                 }
2698
2699                 MUX_TS0710_DEBUG(self->mux_id, "Prepare to send %d bytes from /dev/mux%d", c, line);
2700                 MUX_TS0710_DEBUGHEX(self->mux_id, d_buf, c);
2701
2702                 if (!send_info->frame) {
2703                         printk(KERN_ERR "MUX: %s mux[%d] line[%d] pid[%d] send_info->frame  NULL\n", __FUNCTION__, mux_id, line, current->pid);
2704                         return 0;
2705                 }
2706
2707                 send_info->frame[ring_index] = d_buf;
2708
2709                 queue_uih(send_info, ring_index, c, ts0710, dlci);
2710
2711                 if (line <= MUX_RIL_LINE_END) {
2712                     printk(KERN_ERR "MUX: %s mux[%d] line[%d] pid[%d] write  = %d\n", __FUNCTION__, mux_id, line, current->pid, c);
2713                 }
2714
2715                 send_info->write_index++;
2716
2717                 mutex_unlock(&send_info->send_lock);
2718
2719                 mux_sched_send(self);
2720
2721 //              printk(KERN_ERR "MUX: %s mux[%d] line[%d] pid[%d] write  = %d\n", __FUNCTION__, mux_id, line, current->pid, c);
2722
2723                 MUX_TS0710_DEBUG(mux_id, "line[%d] pid[%d] wait write\n", line, current->pid);
2724
2725                 return c;
2726         } else {
2727                 printk(KERN_ERR "MUX: %s mux[%d] line[%d] pid[%d] not connected\n", __FUNCTION__, mux_id, line, current->pid);
2728                 return -EDISCONNECTED;
2729         }
2730 }
2731
2732 int ts0710_mux_mux_ioctl(int mux_id, int line, unsigned int cmd, unsigned long arg)
2733 {
2734         __u8 dlci;
2735         struct sprd_mux *self = NULL;
2736         ts0710_con *ts0710 = NULL;
2737
2738         UNUSED_PARAM(arg);
2739
2740         if ((line < 0) || (line >= NR_MUXS)) {
2741                 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] is invalid\n", __FUNCTION__, mux_id, line);
2742                 return -EINVAL;
2743         }
2744
2745         self = sprd_mux_mgr[mux_id].handle;
2746
2747         if (!self) {
2748                 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] self is NULL\n", __FUNCTION__, mux_id, line);
2749                 return -ENODEV;
2750         }
2751
2752         ts0710 = self ->connection;
2753         if (!ts0710) {
2754                 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] ts0710 is NULL\n", __FUNCTION__, mux_id, line);
2755                 return -ENODEV;
2756         }
2757
2758         dlci = line2dlci[line];
2759         switch (cmd) {
2760         case TS0710MUX_IO_MSC_HANGUP:
2761                 if (ts0710_msc_msg(ts0710, EA | RTR | DV, MCC_CMD, dlci) < 0) {
2762                         return -EAGAIN;
2763                 } else {
2764                         return 0;
2765                 }
2766
2767         case TS0710MUX_IO_TEST_CMD:
2768                 return ts0710_exec_test_cmd(ts0710);
2769
2770         default:
2771                 break;
2772         }
2773         return -ENOIOCTLCMD;
2774 }
2775
2776 int ts0710_mux_open(int mux_id, int line)
2777 {
2778         int retval;
2779         __u8 dlci;
2780         __u8 cmdline;
2781         __u8 dataline;
2782         mux_send_struct *send_info;
2783         mux_recv_struct *recv_info;
2784         struct sprd_mux *self = NULL;
2785         ts0710_con *ts0710 = NULL;
2786
2787         retval = -ENODEV;
2788
2789         if ((line < 0) || (line >= NR_MUXS)) {
2790                 printk(KERN_ERR "MUX: Error %s line[%d] is wrong\n", __FUNCTION__, line);
2791                 goto out;
2792         }
2793
2794         self = sprd_mux_mgr[mux_id].handle;
2795
2796         mutex_lock(&self->open_mutex[line]);
2797
2798         ts0710 = self->connection;
2799
2800         if (!ts0710) {
2801                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
2802                 goto out;
2803         }
2804
2805         self->open_count[line]++;
2806         dlci = line2dlci[line];
2807
2808         printk(KERN_INFO "MUX: %s id = %d, dlci = %d, pid = %d\n", __FUNCTION__, self->mux_id, dlci, current->pid);
2809
2810         retval = wait_event_interruptible(self->modem_ready, self->mux_status == MUX_STATE_READY);
2811         if (retval < 0) {
2812                 printk(KERN_WARNING "MUX: %s mux[%d] line[%d] pid[%d] ready wait interrupted!\n", __FUNCTION__, self->mux_id, line, current->pid);
2813                 self->open_count[line]--;
2814                 mutex_unlock(&self->open_mutex[line]);
2815                 retval = -EINTR;
2816                 goto out;
2817         }
2818
2819         if (self->cmux_mode == 0) {
2820                 mutex_lock(&self->handshake_mutex);
2821                 printk(KERN_INFO "MUX: id = %d, dlci = %d mode = %d\n", self->mux_id, dlci, self->cmux_mode);
2822                 if (self->cmux_mode == 0) {
2823                         if (mux_handshake(self) != 0) {
2824                                         mutex_unlock(&self->handshake_mutex);
2825                                         self->open_count[line]--;
2826                                         mutex_unlock(&self->open_mutex[line]);
2827                                         printk(KERN_WARNING "\n wrong modem state !!!!\n");
2828                                         retval = -ENODEV;
2829                                         goto out;
2830                         }
2831                         self->cmux_mode = 1;
2832                         wake_up(&self->handshake_ready);
2833
2834                         /*       Open server channel 0 first */
2835                         if ((retval = ts0710_open_channel(ts0710, 0)) != 0) {
2836                                 printk(KERN_ERR "MUX: Error Can't connect server channel 0!\n");
2837                                 ts0710_init(ts0710);
2838                                 self->open_count[line]--;
2839                                 mutex_unlock(&self->handshake_mutex);
2840                                 mutex_unlock(&self->open_mutex[line]);
2841                                 goto out;
2842                         }
2843                 }
2844                 mutex_unlock(&self->handshake_mutex);
2845         }
2846
2847         if ((retval = ts0710_ctrl_channel_status(self->connection)) != 0) {
2848                 ts0710_init(ts0710);
2849                 self->open_count[line]--;
2850                 mutex_unlock(&self->open_mutex[line]);
2851                 goto out;
2852         }
2853
2854         /* Allocate memory first. As soon as connection has been established, MUX may receive */
2855         if (self->mux_send_info_flags[line] == 0) {
2856                 send_info = mux_alloc_send_info(mux_id, line);
2857                 if (!send_info) {
2858                         retval = -ENOMEM;
2859                         self->open_count[line]--;
2860                         mutex_unlock(&self->open_mutex[line]);
2861                         goto out;
2862                 }
2863
2864                 send_info->read_index = 0;
2865                 send_info->write_index = 0;
2866                 send_info->flags = 0;
2867                 mutex_init(&send_info->send_lock);
2868                 init_waitqueue_head(&send_info->tx_wait);
2869
2870                 self->mux_send_info[line] = send_info;
2871                 self->mux_send_info_flags[line] = 1;
2872
2873                 MUX_TS0710_DEBUG(self->mux_id, "Allocate mux_send_info for /dev/mux%d\n", line);
2874         }
2875
2876         if (self->mux_recv_info_flags[line] == 0) {
2877                 recv_info = (mux_recv_struct *) kmalloc(sizeof(mux_recv_struct), GFP_KERNEL);
2878                 if (!recv_info) {
2879                         self->mux_send_info_flags[line] = 0;
2880                         mux_free_send_info(self->mux_send_info[line]);
2881                         self->mux_send_info[line] = 0;
2882
2883                         MUX_TS0710_DEBUG(self->mux_id, "Free mux_send_info for /dev/mux%d\n", line);
2884                         retval = -ENOMEM;
2885
2886                         self->open_count[line]--;
2887                         mutex_unlock(&self->open_mutex[line]);
2888                         goto out;
2889                 }
2890                 recv_info->length = 0;
2891                 recv_info->total = 0;
2892                 recv_info->mux_packet = 0;
2893                 recv_info->pos = 0;
2894                 mutex_init(&recv_info->recv_lock);
2895                 mutex_init(&recv_info->recv_data_lock);
2896                 init_waitqueue_head(&recv_info->rx_wait);
2897
2898                 self->mux_recv_info[line] = recv_info;
2899                 self->mux_recv_info_flags[line] = 1;
2900
2901                 MUX_TS0710_DEBUG(self->mux_id, "Allocate mux_recv_info for /dev/mux%d\n", line);
2902         }
2903
2904         /* Now establish DLCI connection */
2905         cmdline = dlci2line[dlci].cmdline;
2906         dataline = dlci2line[dlci].dataline;
2907
2908         MUX_TS0710_DEBUG(self->mux_id, "dlci = %d cmdline = %d dataline = %d open_count[cmdline] = %d open_count[dataline] = %d\n", dlci, cmdline, dataline, self->open_count[cmdline], self->open_count[dataline]);
2909
2910         if ((self->open_count[cmdline] > 0) || (self->open_count[dataline] > 0)) {
2911                 if ((retval = ts0710_open_channel(ts0710, dlci)) != 0) {
2912                         TS0710_PRINTK("MUX: Can't connected channel %d!\n", dlci);
2913                         ts0710_reset_dlci(ts0710, dlci);
2914
2915                         self->mux_send_info_flags[line] = 0;
2916                         mux_free_send_info(self->mux_send_info[line]);
2917                         self->mux_send_info[line] = 0;
2918
2919                         MUX_TS0710_DEBUG(self->mux_id, "Free mux_send_info for /dev/mux%d\n", line);
2920
2921                         self->mux_recv_info_flags[line] = 0;
2922                         free_mux_recv_struct(self->mux_recv_info[line]);
2923                         self->mux_recv_info[line] = 0;
2924                         MUX_TS0710_DEBUG(self->mux_id, "Free mux_recv_info for /dev/mux%d\n", line);
2925
2926                         self->open_count[line]--;
2927                         mutex_unlock(&self->open_mutex[line]);
2928                         goto out;
2929                 }
2930         }
2931
2932         mutex_unlock(&self->open_mutex[line]);
2933         retval = 0;
2934
2935         out:
2936                 printk(KERN_INFO "MUX: id = %d, dlci = %d, retval = %d\n", self->mux_id, dlci, retval);
2937
2938                 return retval;
2939 }
2940
2941 static inline int rt_policy(int policy)
2942 {
2943         if (unlikely(policy == SCHED_FIFO) || unlikely(policy == SCHED_RR))
2944                 return 1;
2945         return 0;
2946 }
2947
2948 static inline int task_has_rt_policy(struct task_struct *p)
2949 {
2950         return rt_policy(p->policy);
2951 }
2952
2953 /*For BP UART problem Begin*/
2954 #ifdef TS0710SEQ2
2955 static int send_ack(ts0710_con * ts0710, __u8 seq_num, __u8 bp_seq1,
2956                     __u8 bp_seq2)
2957 #else
2958 static int send_ack(ts0710_con * ts0710, __u8 seq_num)
2959 #endif
2960 {
2961         return 0;
2962 }
2963
2964 static int mux_set_thread_pro(int pro)
2965 {
2966         int ret;
2967         struct sched_param s;
2968
2969         /* just for this write, set us real-time */
2970         if (!task_has_rt_policy(current)) {
2971                 struct cred *new = prepare_creds();
2972                 if(!new)
2973                         return -ENOMEM;
2974                 cap_raise(new->cap_effective, CAP_SYS_NICE);
2975                 commit_creds(new);
2976                 s.sched_priority = MAX_RT_PRIO - pro;
2977                 ret = sched_setscheduler(current, SCHED_RR, &s);
2978                 if (ret != 0)
2979                         printk(KERN_WARNING "MUX: set priority failed!\n");
2980         }
2981         return 0;
2982 }
2983
2984 /*For BP UART problem End*/
2985
2986 static void receive_worker(struct sprd_mux *self, int start)
2987 {
2988         int count;
2989         unsigned char *search, *to, *from;
2990         short_frame *short_pkt;
2991         long_frame *long_pkt;
2992         /*For BP UART problem Begin */
2993         __u32 crc_error;
2994         __u8 *uih_data_start;
2995         __u32 uih_len;
2996         /*For BP UART problem End */
2997         int i;
2998
2999         if (!self || !self->io_hal || !self->io_hal->io_read) {
3000                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
3001                 return;
3002         }
3003
3004         if (start) {
3005                 memset(self->tbuf, 0, TS0710MUX_MAX_BUF_SIZE);
3006                 self->tbuf_ptr = self->tbuf;
3007                 self->start_flag = 0;
3008         }
3009
3010         for (i = MUX_VETH_LINE_BEGIN; i <= MUX_VETH_LINE_END; i++) {
3011                 if (self->callback[i].func) {
3012                         (*self->callback[i].func)(i, SPRDMUX_EVENT_READ_IND, NULL, 0, self->callback[i].user_data);
3013                 }
3014         }
3015
3016         count = self->io_hal->io_read(self->tbuf_ptr, TS0710MUX_MAX_BUF_SIZE - (self->tbuf_ptr - self->tbuf));
3017         if (count <= 0 || self->cmux_mode == 0) {
3018                 return;
3019         }
3020
3021         self->tbuf_ptr += count;
3022
3023         if ((self->start_flag != 0) && (self->framelen != -1)) {
3024                 if ((self->tbuf_ptr - self->start_flag) < self->framelen) {
3025                         return;
3026                 }
3027         }
3028
3029         search = &self->tbuf[0];
3030         while (1) {
3031                 if (self->start_flag == 0) {    /* Frame Start Flag not found */
3032                         self->framelen = -1;
3033                         while (search < self->tbuf_ptr) {
3034                                 if (*search == TS0710_BASIC_FLAG) {
3035
3036                                         self->start_flag = search;
3037                                         break;
3038                                 }
3039 #ifdef TS0710LOG
3040                                 else {
3041                                         TS0710_PRINTK(">S %02x %c\n", *search, *search);
3042                                 }
3043 #endif
3044                                 search++;
3045                         }
3046
3047                         if (self->start_flag == 0) {
3048                                 self->tbuf_ptr = &self->tbuf[0];
3049                                 break;
3050                         }
3051                 } else {        /* Frame Start Flag found */
3052                         /* 1 start flag + 1 address + 1 control + 1 or 2 length + lengths data + 1 FCS + 1 end flag */
3053                         /* For BP UART problem 1 start flag + 1 seq_num + 1 address + ...... */
3054                         /*if( (framelen == -1) && ((tbuf_ptr - start_flag) > TS0710_MAX_HDR_SIZE) ) */
3055                         if ((self->framelen == -1) && ((self->tbuf_ptr - self->start_flag) > (TS0710_MAX_HDR_SIZE + SEQ_FIELD_SIZE))) { /*For BP UART problem */
3056                                 /*short_pkt = (short_frame *) (start_flag + 1); */
3057                                 short_pkt = (short_frame *) (self->start_flag + ADDRESS_FIELD_OFFSET);  /*For BP UART problem */
3058                                 if (short_pkt->h.length.ea == 1) {      /* short frame */
3059                                         /*framelen = TS0710_MAX_HDR_SIZE + short_pkt->h.length.len + 1; */
3060                                         self->framelen = TS0710_MAX_HDR_SIZE + short_pkt->h.length.len + 1 + SEQ_FIELD_SIZE;    /*For BP UART problem */
3061                                 } else {        /* long frame */
3062                                         /*long_pkt = (long_frame *) (start_flag + 1); */
3063                                         long_pkt = (long_frame *) (self->start_flag + ADDRESS_FIELD_OFFSET);    /*For BP UART problem */
3064                                         /*framelen = TS0710_MAX_HDR_SIZE + GET_LONG_LENGTH( long_pkt->h.length ) + 2; */
3065                                         self->framelen = TS0710_MAX_HDR_SIZE + GET_LONG_LENGTH(long_pkt->h.length) + 2 + SEQ_FIELD_SIZE;        /*For BP UART problem */
3066                                 }
3067
3068                                 /*if( framelen > TS0710MUX_MAX_TOTAL_FRAME_SIZE ) { */
3069                                 if (self->framelen > (TS0710MUX_MAX_TOTAL_FRAME_SIZE + SEQ_FIELD_SIZE)) {       /*For BP UART problem */
3070                                         MUX_TS0710_LOGSTR_FRAME(self->mux_id, 0, self->start_flag, (self->tbuf_ptr - self->start_flag));
3071                                         TS0710_PRINTK("MUX Error: %s: frame length:%d is bigger than Max total frame size:%d\n",
3072                  /*__FUNCTION__, framelen, TS0710MUX_MAX_TOTAL_FRAME_SIZE);*/
3073                                              __FUNCTION__, self->framelen, (TS0710MUX_MAX_TOTAL_FRAME_SIZE + SEQ_FIELD_SIZE));  /*For BP UART problem */
3074                                         search = self->start_flag + 1;
3075                                         self->start_flag = 0;
3076                                         self->framelen = -1;
3077                                         continue;
3078                                 }
3079                         }
3080
3081                         if ((self->framelen != -1)
3082                             && ((self->tbuf_ptr - self->start_flag) >= self->framelen)) {
3083                                 if (*(self->start_flag + self->framelen - 1) == TS0710_BASIC_FLAG) {    /* OK, We got one frame */
3084
3085                                         /*For BP UART problem Begin */
3086
3087                                         MUX_TS0710_LOGSTR_FRAME(self->mux_id, 0, self->start_flag, self->framelen);
3088                                         MUX_TS0710_DEBUGHEX(self->mux_id, self->start_flag, self->framelen);
3089                                         short_pkt = (short_frame *) (self->start_flag + ADDRESS_FIELD_OFFSET);
3090                                         if ((short_pkt->h.length.ea) == 0) {
3091                                                 long_pkt = (long_frame *) (self->start_flag + ADDRESS_FIELD_OFFSET);
3092                                                 uih_len = GET_LONG_LENGTH(long_pkt->h.length);
3093                                                 uih_data_start = long_pkt->h.data;
3094
3095                                                 crc_error = crc_check((__u8*) (self->start_flag + SLIDE_BP_SEQ_OFFSET), LONG_CRC_CHECK + 1, *(uih_data_start + uih_len));
3096                                         } else {
3097                                                 uih_len = short_pkt->h.length.len;
3098                                                 uih_data_start = short_pkt->data;
3099
3100                                                 crc_error = crc_check((__u8*) (self->start_flag + SLIDE_BP_SEQ_OFFSET), SHORT_CRC_CHECK + 1, *(uih_data_start + uih_len));
3101                                         }
3102
3103                                         if (!crc_error) {
3104                                                 if (1)  /*expect_seq == *(start_flag + SLIDE_BP_SEQ_OFFSET)*/
3105                                                 {
3106                                                         self->expect_seq = *(self->start_flag + SLIDE_BP_SEQ_OFFSET);
3107                                                         self->expect_seq++;
3108                                                         if (self->expect_seq >= 4){
3109                                                                 self->expect_seq = 0;
3110                                                         }
3111 #ifdef TS0710SEQ2
3112                                                         send_ack(self->connection, self->expect_seq, *(self->start_flag + FIRST_BP_SEQ_OFFSET), *(self->start_flag + SECOND_BP_SEQ_OFFSET));
3113 #else
3114                                                         send_ack(self->connection, self->expect_seq);
3115 #endif
3116
3117                                                         ts0710_recv_data(self->connection, self->start_flag + ADDRESS_FIELD_OFFSET, self->framelen - 2 - SEQ_FIELD_SIZE);
3118                                                 } else {
3119
3120 #ifdef TS0710DEBUG
3121                                                         if (*(self->start_flag + SLIDE_BP_SEQ_OFFSET) != 0x9F) {
3122 #endif
3123
3124                                                                 TS0710_PRINTK("MUX sequence number %d is not expected %d, discard data!\n", *(self->start_flag + SLIDE_BP_SEQ_OFFSET), self->expect_seq);
3125
3126 #ifdef TS0710SEQ2
3127                                                                 send_ack(self->connection, self->expect_seq, *(self->start_flag + FIRST_BP_SEQ_OFFSET), *(self->start_flag + SECOND_BP_SEQ_OFFSET));
3128 #else
3129                                                                 send_ack(self->connection, self->expect_seq);
3130 #endif
3131
3132 #ifdef TS0710DEBUG
3133                                                         } else {
3134                                                                 *(uih_data_start + uih_len) = 0;
3135                                                                 TS0710_PRINTK("MUX bp log: %s\n", uih_data_start);
3136                                                         }
3137 #endif
3138
3139                                                 }
3140                                         } else {        /* crc_error */
3141                                                 search = self->start_flag + 1;
3142                                                 self->start_flag = 0;
3143                                                 self->framelen = -1;
3144                                                 continue;
3145                                         }       /*End if(!crc_error) */
3146
3147                                         search = self->start_flag + self->framelen;
3148                                 } else {
3149                                         MUX_TS0710_LOGSTR_FRAME(self->mux_id, 0, self->start_flag, self->framelen);
3150                                         MUX_TS0710_DEBUGHEX(self->mux_id, self->start_flag, self->framelen);
3151                                         TS0710_PRINTK("MUX: Lost synchronization!\n");
3152                                         search = self->start_flag + 1;
3153                                 }
3154
3155                                 self->start_flag = 0;
3156                                 self->framelen = -1;
3157                                 continue;
3158                         }
3159
3160                         if (self->start_flag != &self->tbuf[0]) {
3161
3162                                 to = self->tbuf;
3163                                 from = self->start_flag;
3164                                 count = self->tbuf_ptr - self->start_flag;
3165                                 while (count--) {
3166                                         *to++ = *from++;
3167                                 }
3168
3169                                 self->tbuf_ptr -= (self->start_flag - self->tbuf);
3170                                 self->start_flag = self->tbuf;
3171
3172                         }
3173                         break;
3174                 }               /* End Frame Start Flag found */
3175         }                       /* End while(1) */
3176 }
3177
3178 static int mux_receive_thread(void *data)
3179 {
3180         int start = 1;
3181         struct sprd_mux *self = data;
3182
3183         if (!self) {
3184                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
3185                 return 0;
3186         }
3187
3188         printk(KERN_ERR "MUX: id = %d %s entered\n", self->mux_id, __FUNCTION__);
3189
3190         mux_set_thread_pro(95);
3191         while (!kthread_should_stop()) {
3192                 if (self->mux_exiting == 1) {
3193                         self->mux_exiting = 2;
3194                         return 0;
3195                 }
3196
3197                 wait_event(self->handshake_ready, self->cmux_mode == 1);
3198
3199                 receive_worker(self, start);
3200                 start = 0;
3201         }
3202         return 0;
3203 }
3204
3205 static int mux_send_thread(void *private_)
3206 {
3207         ts0710_con *ts0710;
3208         __u8 j;
3209         mux_send_struct *send_info;
3210         __u8 dlci;
3211         struct sprd_mux *self;
3212         __u32 ring_index;
3213         __u32 num;
3214
3215         self = (struct sprd_mux *)(private_);
3216
3217         if (!self) {
3218                 printk(KERN_ERR "MUX: Error %s Self is NULL\n", __FUNCTION__);
3219                 return 0;
3220         }
3221
3222         printk(KERN_ERR "MUX: id = %d %s entered\n", self->mux_id, __FUNCTION__);
3223
3224         ts0710 = self->connection;
3225         if (!ts0710) {
3226                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
3227                 return 0;
3228         }
3229
3230         if (ts0710->dlci[0].state == FLOW_STOPPED) {
3231                 MUX_TS0710_DEBUG(self->mux_id, "Flow stopped on all channels\n");
3232                 return 0;
3233         }
3234
3235         mux_set_thread_pro(80);
3236
3237         while (!kthread_should_stop()) {
3238
3239                 wait_for_completion_interruptible(&self->send_completion);
3240                 for (j = 0; j < NR_MUXS; j++) {
3241                         wait_event(self->modem_ready, self->mux_status == MUX_STATE_READY);
3242
3243                         if (!(self->mux_send_info_flags[j])) {
3244                                 continue;
3245                         }
3246
3247                         send_info = self->mux_send_info[j];
3248                         if (!send_info) {
3249                                 continue;
3250                         }
3251
3252                         if (send_info->write_index == send_info->read_index) {
3253                                 continue;
3254                         }
3255
3256                         dlci = line2dlci[j];
3257                         if (ts0710->dlci[dlci].state == FLOW_STOPPED) {
3258                                 MUX_TS0710_DEBUG(self->mux_id, "Flow stopped on channel DLCI: %d\n", dlci);
3259                                 continue;
3260                         } else if (ts0710->dlci[dlci].state != CONNECTED) {
3261                                 MUX_TS0710_DEBUG(self->mux_id, "DLCI %d not connected\n", dlci);
3262                                 send_info->read_index = send_info->write_index;
3263                                 wake_up_interruptible(&send_info->tx_wait);
3264                                 continue;
3265                         }
3266
3267                         while(send_info->write_index != send_info->read_index) {
3268                                 ring_index = send_info->read_index % ringbuf_num[self->mux_id][j];
3269                                 MUX_TS0710_DEBUG(self->mux_id, "Send queued UIH for /dev/mux%d ring_index = %d, len = %d", j,ring_index,  send_info->length[ring_index]);
3270
3271                                 if (send_info->length[ring_index] <= TS0710MUX_SERIAL_BUF_SIZE) {
3272                                         if (basic_write(ts0710, (__u8 *) send_info->frame[ring_index], send_info->length[ring_index]) <= 0 ) {
3273                                                 printk("[%s]: %s /dev/mux%d index = %d basic_write fail!\n", sprd_mux_mgr[self->mux_id].mux_name, __FUNCTION__, j, ring_index);
3274                                                 break;
3275                                         }
3276                                 } else {
3277                                         printk("[%s]: %s /dev/mux%d send length is exceed %d\n", sprd_mux_mgr[self->mux_id].mux_name, __FUNCTION__, j, send_info->length[ring_index]);
3278                                 }
3279                                 send_info->length[ring_index] = 0;
3280                                 send_info->read_index++;
3281                                 num = send_info->write_index - send_info->read_index;
3282                                 if (send_info->need_notify || 0 == num) {
3283                                         if (num <= ringbuf_num[self->mux_id][j]/2) {
3284                                                 send_info->need_notify = false;
3285 //                                              printk("[%s]: %s /dev/mux%d num = %d, cnt = %u\n", sprd_mux_mgr[self->mux_id].mux_name, __FUNCTION__, j, num, cnt++);
3286                                                 if (self->callback[j].func) {
3287                                                         (*self->callback[j].func)(j, SPRDMUX_EVENT_COMPLETE_WRITE, (__u8 *)send_info->frame, 0, self->callback[j].user_data);
3288                                                 }
3289                                         }
3290                                 }
3291                         }
3292
3293                         wake_up_interruptible(&send_info->tx_wait);
3294                 }                       /* End for() loop */
3295
3296         }
3297         return 0;
3298 }
3299
3300
3301 ssize_t mux_proc_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
3302 {
3303         return seq_read(file, buf, size, ppos);
3304 }
3305
3306 static int mux_proc_show(struct seq_file *seq, void *v)
3307 {
3308         char mux_buf[MUX_MODE_MAX_LEN + 1];
3309
3310         memset(mux_buf, 0, sizeof(mux_buf));
3311         snprintf(mux_buf, MUX_MODE_MAX_LEN, "%d\n", mux_mode);
3312         seq_puts(seq, mux_buf);
3313
3314         return 0;
3315 }
3316 static int mux_proc_open(struct inode *inode, struct file *file)
3317 {
3318         return single_open(file, mux_proc_show, inode->i_private);
3319 }
3320
3321 static ssize_t mux_proc_write(struct file *file, const char __user *buf, size_t len, loff_t *ppos)
3322 {
3323         char mux_buf[len + 1];
3324         int val;
3325
3326         memset(mux_buf, 0, len + 1);
3327         if (len > 0) {
3328                 if (copy_from_user(mux_buf, buf, len)) {
3329                    printk(KERN_ERR "MUX: Error %s failed to copy from user!\n", __FUNCTION__);
3330                    return -EFAULT;
3331
3332                 }
3333
3334                 val = simple_strtoul(mux_buf, NULL, 10);
3335                 mux_mode = val;
3336         }
3337
3338         return len;
3339 }
3340
3341 static int mux_create_proc(void)
3342 {
3343         struct proc_dir_entry *mux_entry;
3344         static const struct file_operations mux_fops = {
3345                 .owner = THIS_MODULE,
3346                 .open = mux_proc_open,
3347                 .read = mux_proc_read,
3348                 .write = mux_proc_write,
3349                 .llseek = seq_lseek,
3350                 .release = single_release,
3351         };
3352
3353         mux_entry = proc_create("mux_mode", 0666, NULL, &mux_fops);
3354         if (!mux_entry) {
3355                 printk(KERN_ERR "MUX: Error Can not create mux proc entry\n");
3356                 return -ENOMEM;
3357         }
3358
3359         return 0;
3360 }
3361
3362 static void mux_set_ringbuf_num(void)
3363 {
3364         int mux_id;
3365         int line;
3366
3367         for(mux_id = SPRDMUX_ID_SPI; mux_id < SPRDMUX_ID_MAX; mux_id++) {
3368                 for(line = 0; line < NR_MUXS; line++) {
3369                         if (mux_id == SPRDMUX_ID_SDIO && (line >= MUX_VETH_LINE_BEGIN && line <=MUX_VETH_LINE_END)) {
3370                                 ringbuf_num[mux_id][line] = MUX_VETH_RINGBUFER_NUM;
3371                         } else {
3372                                 /* Default */
3373                                 ringbuf_num[mux_id][line] = 1;
3374                         }
3375                 }
3376         }
3377 }
3378
3379 static int mux_line_state(SPRDMUX_ID_E mux_id, int line)
3380 {
3381         struct sprd_mux *self = NULL;
3382         mux_send_struct *send_info;
3383
3384         self = sprd_mux_mgr[mux_id].handle;
3385
3386         send_info = self->mux_send_info[line];
3387
3388         if (!send_info) {
3389                 printk(KERN_ERR "MUX Error: %s: mux_send_info[%d][%d] == 0\n", __FUNCTION__, mux_id, line);
3390                 return 1;
3391         }
3392
3393         if (send_info->write_index - send_info->read_index >= ringbuf_num[mux_id][line]) {
3394                 /* No idle ring buffer */
3395                 return 1;
3396         }
3397
3398         return 0;
3399 }
3400
3401 int sprdmux_line_busy(SPRDMUX_ID_E mux_id, int line)
3402 {
3403         return mux_line_state(mux_id, line);
3404 }
3405
3406 void sprdmux_set_line_notify(SPRDMUX_ID_E mux_id, int line, __u8 notify)
3407
3408 {
3409         struct sprd_mux *self = NULL;
3410         mux_send_struct *send_info;
3411
3412         self = sprd_mux_mgr[mux_id].handle;
3413
3414         send_info = self->mux_send_info[line];
3415
3416         if (!send_info) {
3417                 printk(KERN_ERR "MUX Error: %s: mux_send_info[%d][%d] == 0\n", __FUNCTION__, mux_id, line);
3418                 return;
3419         }
3420
3421         send_info->need_notify = notify;
3422 }
3423
3424 static mux_send_struct * mux_alloc_send_info(SPRDMUX_ID_E mux_id, int line)
3425 {
3426         mux_send_struct *send_info_ptr = NULL;
3427
3428         send_info_ptr = (mux_send_struct *) kzalloc(sizeof(mux_send_struct), GFP_KERNEL);
3429         if (!send_info_ptr) {
3430                 return NULL;
3431         }
3432
3433         send_info_ptr->buf = (__u8 *)vmalloc(sizeof(__u8) * TS0710MUX_SEND_BUF_SIZE * ringbuf_num[mux_id][line]);
3434         if (!send_info_ptr->buf) {
3435                 kfree(send_info_ptr);
3436                 return NULL;
3437         }
3438
3439         send_info_ptr->length = (__u16 *)kzalloc(sizeof(__u16) * ringbuf_num[mux_id][line], GFP_KERNEL);
3440         if (!send_info_ptr->length) {
3441                 vfree(send_info_ptr->buf);
3442                 kfree(send_info_ptr);
3443                 return NULL;
3444         }
3445
3446         send_info_ptr->frame = (__u8 **)kzalloc(sizeof(__u8 *) * ringbuf_num[mux_id][line], GFP_KERNEL);
3447
3448         if (!send_info_ptr->frame) {
3449                 kfree(send_info_ptr->length);
3450                 vfree(send_info_ptr->buf);
3451                 kfree(send_info_ptr);
3452                 return NULL;
3453         }
3454
3455         return send_info_ptr;
3456 }
3457
3458 static void mux_free_send_info(mux_send_struct * send_info)
3459 {
3460         if (!send_info) {
3461                 return;
3462         }
3463
3464         if (send_info->frame) {
3465                 kfree(send_info->frame);
3466                 send_info->frame = NULL;
3467         }
3468
3469         if (send_info->length) {
3470                 kfree(send_info->length);
3471                 send_info->length = NULL;
3472         }
3473
3474         if (send_info->buf) {
3475                 vfree(send_info->buf);
3476                 send_info->buf = NULL;
3477
3478         }
3479
3480         kfree(send_info);
3481         send_info = NULL;
3482 }
3483
3484 static void mux_remove_proc(void)
3485 {
3486         remove_proc_entry("mux_mode", NULL);    /* remove /proc/mux_mode */
3487 }
3488
3489 int ts0710_mux_init(void)
3490 {
3491         create_crctable(crctable);
3492
3493 //      mux_mgr_init(sprd_mux_mgr);
3494
3495         if (mux_create_proc()) {
3496                 printk(KERN_ERR "MUX: Error %s create mux proc interface failed!\n", __FUNCTION__);
3497         }
3498
3499         mux_set_ringbuf_num();
3500         return 0;
3501 }
3502
3503 void ts0710_mux_exit(void)
3504 {
3505         mux_remove_proc();
3506         mux_mgr_init(sprd_mux_mgr);
3507 }
3508
3509 int ts0710_mux_create(int mux_id)
3510 {
3511         struct sprd_mux *self = NULL;
3512         int j, rval = 0;
3513
3514         if (mux_id < 0 || mux_id >= SPRDMUX_ID_MAX) {
3515                 printk(KERN_ERR "MUX: Error %sInvalid Param\n",__FUNCTION__);
3516                 rval = -EINVAL;
3517                 goto err_iomux;
3518         }
3519
3520         self = (struct sprd_mux *)kzalloc(sizeof(struct sprd_mux), GFP_KERNEL);
3521
3522         if (!self) {
3523                 printk(KERN_ERR "MUX: Error %s no memory for self\n",__FUNCTION__);
3524                 rval = -ENOMEM;
3525                 goto err_sprd_mux;
3526         }
3527
3528         self->mux_id = mux_id;
3529
3530         self->connection = (ts0710_con *)kzalloc(sizeof(ts0710_con), GFP_KERNEL);
3531
3532         if (!self->connection) {
3533                 printk(KERN_ERR "MUX: Error %s no memory for connection\n",__FUNCTION__);
3534                 rval = -ENOMEM;
3535                 goto err_conn;
3536         }
3537
3538         self->connection->user_data = (void *)self;
3539
3540         ts0710_init(self->connection);
3541
3542         ts0710_init_waitqueue(self->connection);
3543
3544         mutex_init(&self->handshake_mutex);
3545
3546         for (j = 0; j < NR_MUXS; j++) {
3547                 self->mux_send_info_flags[j] = 0;
3548                 self->mux_send_info[j] = 0;
3549                 self->mux_recv_info_flags[j] = 0;
3550                 self->mux_recv_info[j] = 0;
3551                 self->open_count[j] = 0;
3552
3553                 mutex_init(&self->open_mutex[j]);
3554         }
3555
3556         self->framelen = -1;
3557         self->expect_seq = 0;
3558         self->mux_status = MUX_STATE_NOT_READY;
3559
3560         init_completion(&self->send_completion);
3561         init_waitqueue_head(&self->handshake_ready);
3562         init_waitqueue_head(&self->modem_ready);
3563
3564         /*create mux_send thread*/
3565         self->mux_send_kthread = kthread_create(mux_send_thread, self, "mux_send");
3566         if(IS_ERR(self->mux_send_kthread)) {
3567                 printk(KERN_ERR "MUX: Error %s Unable to create mux_send thread err = %ld\n", __FUNCTION__, PTR_ERR(self->mux_send_kthread));
3568                 rval = PTR_ERR(self->mux_send_kthread);
3569                 goto err_send_thread;
3570         }
3571
3572         wake_up_process(self->mux_send_kthread);
3573
3574         /*create receive thread*/
3575         self->mux_recv_kthread = kthread_create(mux_receive_thread, self, "mux_receive");
3576         if(IS_ERR(self->mux_recv_kthread)) {
3577                 printk(KERN_ERR "MUX: Error %s Unable to create mux_receive thread err = %ld\n", __FUNCTION__, PTR_ERR(self->mux_recv_kthread));
3578                 rval = PTR_ERR(self->mux_recv_kthread);
3579                 goto err_recv_thread;
3580         }
3581         wake_up_process(self->mux_recv_kthread);
3582
3583         self->io_hal = &sprd_mux_mgr[mux_id].mux;
3584         sprd_mux_mgr[mux_id].handle = self;
3585
3586         return rval;
3587
3588 err_recv_thread:
3589         kthread_stop(self->mux_send_kthread);
3590         self->mux_send_kthread = NULL;
3591 err_send_thread:
3592         kfree(self->connection);
3593 err_conn:
3594         kfree(self);
3595 err_sprd_mux:
3596 err_iomux:
3597         printk(KERN_ERR "MUX: Error %s Create Failed \n",__FUNCTION__);
3598
3599         return rval;
3600 }
3601
3602
3603
3604
3605 void ts0710_mux_destory(int mux_id)
3606 {
3607         int j;
3608         struct sprd_mux *self = NULL;
3609
3610         if (mux_id < 0 || mux_id >= SPRDMUX_ID_MAX) {
3611                 printk(KERN_ERR "MUX: Error %sInvalid Param\n",__FUNCTION__);
3612                 return;
3613         }
3614
3615         self = sprd_mux_mgr[mux_id].handle;
3616
3617         if (!self) {
3618                 printk(KERN_ERR "MUX: Error %s Invalid Param self = %x\n", __FUNCTION__, (int)self);
3619                 return;
3620         }
3621
3622         for (j = 0; j < NR_MUXS; j++) {
3623                 if (self->mux_send_info_flags[j]) {
3624                         mux_free_send_info(self->mux_send_info[j]);
3625                         self->mux_send_info_flags[j] = 0;
3626                 }
3627
3628                 if ((self->mux_recv_info_flags[j]) && (self->mux_recv_info[j])) {
3629                         free_mux_recv_struct(self->mux_recv_info[j]);
3630                 }
3631                 self->mux_recv_info_flags[j] = 0;
3632                 self->mux_recv_info[j] = 0;
3633         }
3634         self->mux_exiting = 1;
3635
3636         ts0710_close_channel(self->connection, 0);
3637         TS0710_SIG2APLOGD();
3638         self->cmux_mode = 0;
3639
3640         if (!self->io_hal || !self->io_hal->io_stop) {
3641                 self->io_hal->io_stop(SPRDMUX_READ);
3642         }
3643
3644         while (self->mux_exiting == 1) {
3645                 msleep(10);
3646         }
3647
3648         if(self->mux_recv_kthread) {
3649                 kthread_stop(self->mux_recv_kthread);
3650                 self->mux_recv_kthread = NULL;
3651         }
3652
3653         if(self->mux_send_kthread) {
3654                 kthread_stop(self->mux_send_kthread);
3655                 self->mux_send_kthread = NULL;
3656         }
3657
3658         if (self->connection) {
3659                 kfree(self->connection);
3660         }
3661
3662         if (self->mux_recover_kthread) {
3663                 kthread_stop(self->mux_recover_kthread);
3664                 self->mux_recover_kthread = NULL;
3665         }
3666         kfree(self);
3667 }
3668
3669 static void mux_print_mux_mgr(void)
3670 {
3671         int j = 0;
3672
3673         printk(KERN_INFO "No    MUX_ID          Name            Handle\n");
3674
3675         for (j = 0; j < SPRDMUX_MAX_NUM; j++) {
3676                 printk(KERN_INFO "%d            %d                      %s              %d\n", j, sprd_mux_mgr[j].mux_id,
3677                                 sprd_mux_mgr[j].mux_name, (uint32_t)sprd_mux_mgr[j].handle);
3678         }
3679 }
3680 static void mux_mgr_init(mux_info *mux_mgr)
3681 {
3682         int j = 0;
3683         mux_print_mux_mgr();
3684
3685         if (mux_mgr) {
3686                 for (j = 0; j < SPRDMUX_MAX_NUM; j++) {
3687                         mux_mgr[j].handle = NULL;
3688                 }
3689         }
3690 }
3691
3692 int sprdmux_register(struct sprdmux *mux)
3693 {
3694         if (!mux || mux->id < 0 || mux->id >= SPRDMUX_ID_MAX ) {
3695                 printk(KERN_ERR "MUX: %s Invalid Param\n", __FUNCTION__);
3696                 return -EINVAL;
3697         }
3698
3699         memcpy(&sprd_mux_mgr[mux->id].mux, mux, sizeof(struct sprdmux));
3700
3701         printk(KERN_INFO "ts0710MUX[%d] 0x%x, 0x%x 0x%x\n", mux->id, (unsigned int)mux->io_write, (unsigned int)mux->io_read, (unsigned int)mux->io_stop);
3702
3703         ts0710_mux_create(mux->id);
3704
3705         return 0;
3706 }
3707
3708 void sprdmux_unregister(SPRDMUX_ID_E mux_id)
3709 {
3710         if (mux_id >= SPRDMUX_ID_MAX || mux_id < 0) {
3711                 printk(KERN_ERR "MUX: Error %s Invalid Param mux_id = %d\n", __FUNCTION__, mux_id);
3712                 return;
3713         }
3714
3715         memset(&sprd_mux_mgr[mux_id].mux, 0, sizeof(struct sprdmux));
3716         ts0710_mux_destory(mux_id);
3717 }
3718
3719 int sprdmux_open(SPRDMUX_ID_E mux_id, int index)
3720 {
3721         int rval = 0;
3722
3723         if (mux_id < 0 || mux_id >= SPRDMUX_ID_MAX || index < 0 || index >= NR_MUXS) {
3724                 printk(KERN_ERR "MUX: Error %s Invalid Param mux_id = %d, index = %d\n", __FUNCTION__, mux_id, index);
3725                 return -EINVAL;
3726         }
3727
3728         rval = ts0710_mux_status(mux_id);
3729
3730         if (rval != 0) {
3731                 printk(KERN_ERR "MUX: Error %s [%d][%d] mux_status is Not OK\n", __FUNCTION__, mux_id, index);
3732                 return rval;
3733         }
3734
3735         return ts0710_mux_open(mux_id, index);
3736 }
3737
3738 void sprdmux_close(SPRDMUX_ID_E mux_id, int index)
3739 {
3740         if (mux_id < 0 || mux_id >= SPRDMUX_ID_MAX || index < 0 || index >= NR_MUXS) {
3741                 printk(KERN_ERR "MUX: Error %s Invalid Param mux_id = %d, index = %d\n", __FUNCTION__, mux_id, index);
3742                 return;
3743         }
3744
3745         if (ts0710_mux_status(mux_id) != 0) {
3746                 printk(KERN_ERR "MUX: Error %s [%d][%d] mux_status is Not OK\n", __FUNCTION__, mux_id, index);
3747                 return;
3748         }
3749
3750         ts0710_mux_close(mux_id, index);
3751 }
3752
3753 int sprdmux_write(SPRDMUX_ID_E mux_id, int index, const unsigned char *buf, int count)
3754 {
3755         int rval = 0;
3756
3757         if (mux_id < 0 || mux_id >= SPRDMUX_ID_MAX || index < 0 || index >= NR_MUXS) {
3758                 printk(KERN_ERR "MUX: Error %s Invalid Param mux_id = %d, index = %d\n", __FUNCTION__, mux_id, index);
3759                 return -EINVAL;
3760         }
3761
3762         rval = ts0710_mux_status(mux_id);
3763
3764         if (rval != 0) {
3765                 printk(KERN_ERR "MUX: Error %s [%d][%d] mux_status is Not OK\n", __FUNCTION__, mux_id, index);
3766                 return rval;
3767         }
3768
3769         return ts0710_mux_write(mux_id, index, buf, count, 0);
3770 }
3771
3772 int sprdmux_register_notify_callback(SPRDMUX_ID_E mux_id, struct sprdmux_notify *notify)
3773 {
3774         struct sprd_mux *self = NULL;
3775
3776         if (mux_id < 0 || mux_id >= SPRDMUX_ID_MAX || !notify || notify->index >= NR_MUXS) {
3777                 printk(KERN_ERR "MUX: Error %s Invalid Param\n", __FUNCTION__);
3778                 return -EINVAL;
3779         }
3780
3781         self = sprd_mux_mgr[mux_id].handle;
3782
3783         if (self) {
3784                 if (!self->callback[notify->index].func) {
3785                         self->callback[notify->index].func = notify->func;
3786                         self->callback[notify->index].user_data = notify->user_data;
3787                 }
3788
3789                 return 0;
3790         }
3791
3792         printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
3793         return -ENODEV;
3794 }
3795
3796 static void mux_display_recv_info(const char * tag, int mux_id, int line)
3797 {
3798         struct sprd_mux *self = NULL;
3799         mux_recv_struct *recv_info;
3800         int sum = 0;
3801         mux_recv_packet *recv_packet;
3802
3803         if (mux_id < 0 || mux_id >= SPRDMUX_ID_MAX) {
3804                 printk(KERN_ERR "MUX: Error %s %sInvalid Param mux_id = %d\n", __FUNCTION__, tag, mux_id);
3805                 return;
3806         }
3807
3808         if ((line < 0) || (line >= NR_MUXS)) {
3809                 printk(KERN_ERR "MUX: Error %s %sline[%d] is wrong\n", __FUNCTION__, tag, line);
3810                 return;
3811
3812         }
3813
3814         self = sprd_mux_mgr[mux_id].handle;
3815
3816         if (!self) {
3817                 printk(KERN_ERR "MUX[%d]: Error %s %s self is NULL\n", mux_id,  __FUNCTION__, tag);
3818                 mux_print_mux_mgr();
3819                 return;
3820         }
3821
3822         recv_info = self->mux_recv_info[line];
3823
3824         if (recv_info == NULL){
3825                 printk(KERN_ERR "MUX: Error %s %s mux_recv_info is NULL\n", __FUNCTION__, tag);
3826                 return;
3827         }
3828
3829         sum += recv_info->length;
3830
3831         while((recv_packet = recv_info->mux_packet) != NULL) {
3832                 sum += recv_packet->length;
3833                 recv_packet = recv_packet->next;
3834         }
3835
3836         if (sum != recv_info->total || sum != self->check_read_sum[line]) {
3837                 printk(KERN_ERR "MUX: Error %s %s mux_id = %d, line = %d, total = %d, sum = %d check = %d len = %d\n", __FUNCTION__, tag, mux_id, line, recv_info->total, sum, self->check_read_sum[line], recv_info->length);
3838                 while((recv_packet = recv_info->mux_packet) != NULL) {
3839                         sum += recv_packet->length;
3840                         recv_packet = recv_packet->next;
3841                         printk(KERN_ERR "MUX: Error %s %s recv_packet->length = %d\n", __FUNCTION__, tag, recv_packet->length);
3842                 }
3843         }
3844 }
3845
3846 int ts0710_mux_status(int mux_id)
3847 {
3848         if (mux_id >= SPRDMUX_ID_MAX || mux_id < 0) {
3849                 printk(KERN_ERR "MUX: Error %s [%d] Invalid Param\n", __FUNCTION__, mux_id);
3850                 return -EINVAL;
3851         }
3852
3853         if (sprd_mux_mgr[mux_id].handle && sprd_mux_mgr[mux_id].mux_id == mux_id
3854                 && sprd_mux_mgr[mux_id].mux.io_read != NULL && sprd_mux_mgr[mux_id].mux.io_write!= NULL && sprd_mux_mgr[mux_id].mux.io_stop!= NULL) {
3855
3856                 return 0;
3857         }
3858
3859         printk(KERN_ERR "MUX: Error %s  [%d] status is Not OK\n", __FUNCTION__, mux_id);
3860
3861         return -ENODEV;
3862 }
3863
3864 static int mux_handshake(struct sprd_mux *self)
3865 {
3866         char buffer[256];
3867         char *buff = buffer;
3868         int count, i = 0;
3869
3870         MUX_TS0710_DEBUG(self->mux_id, "cmux_mode = %d\n", self->cmux_mode);
3871
3872         if (self->cmux_mode == 1) {
3873                 printk(KERN_ERR "MUX: %s mux_mode is incorrect!\n", __FUNCTION__);
3874                 return 0;
3875         }
3876
3877         memset(buffer, 0, 256);
3878         printk(KERN_INFO "\n cmux say hello >, id %d \n", self->mux_id);
3879
3880         if (mux_mode == 1) {
3881                 count = self->io_hal->io_write("AT+SMMSWAP=0\r", strlen("AT+SMMSWAP=0\r"));
3882         } else {
3883                 count = self->io_hal->io_write("AT\r", strlen("AT\r"));
3884         }
3885
3886         if (count < 0) {
3887                 printk(KERN_INFO "\n MUX: id = %d,cmux write stoped for crash\n", self->mux_id);
3888                 return -1;
3889         }
3890
3891         /*wait for response "OK \r" */
3892         printk(KERN_INFO "\n MUX: id = %d,cmux receiving\n", self->mux_id);
3893         mux_init_timer(self);
3894         while (1) {
3895                 mux_start_timer(self);
3896                 count = self->io_hal->io_read(buff, sizeof(buffer) - (buff - buffer));
3897                 mux_stop_timer(self);
3898                 printk(KERN_INFO "MUX: id = %d,ts mux received %d chars\n", self->mux_id, count);
3899                 if(count > 0) {
3900                         buff += count;
3901                         if (findInBuf(buffer, 256, "OK")) {
3902                                 break;
3903                         } else if (findInBuf(buffer, 256, "ERROR")) {
3904                                 printk(KERN_INFO "\n MUX: id = %d,wrong modem state !!!!\n", self->mux_id);
3905                                 break;
3906                         }
3907                 } else if (count == 0){
3908                         msleep(200);
3909                         continue;
3910                 } else {
3911                         if (self->mux_status == MUX_STATE_CRASHED) {
3912                                 printk(KERN_INFO "\n MUX: id = %d,cmux read stoped for crash\n", self->mux_id);
3913                                 return -1;
3914                         }
3915                         msleep(2000);
3916                         if (mux_mode == 1) {
3917                                 count = self->io_hal->io_write("AT+SMMSWAP=0\r", strlen("AT+SMMSWAP=0\r"));
3918                         } else {
3919                                 count = self->io_hal->io_write("AT\r", strlen("AT\r"));
3920                         }
3921                         if (count < 0 && self->mux_status == MUX_STATE_CRASHED) {
3922                                 printk(KERN_INFO "\n MUX: id = %d,cmux read stoped for crash\n", self->mux_id);
3923                                 return -1;
3924                         }
3925                         i++;
3926                 }
3927                 if (i > 5) {
3928                         printk(KERN_WARNING "\n MUX: id = %d,wrong modem state !!!!\n", self->mux_id);
3929                         return -1;
3930                 }
3931         }
3932
3933         count = self->io_hal->io_write("at+cmux=0\r", strlen("at+cmux=0\r"));
3934         if (count < 0) {
3935                 printk(KERN_INFO "\n MUX: id = %d,cmux write stoped\n", self->mux_id);
3936                 return -1;
3937         }
3938
3939         count = self->io_hal->io_read(buffer, sizeof(buffer));
3940         if (count < 0) {
3941                 printk(KERN_INFO "\n MUX: id = %d,cmux read stoped\n", self->mux_id);
3942                 return -1;
3943         }
3944
3945         printk(KERN_INFO "MUX: id = %d, handshake OK\n", self->mux_id);
3946
3947         return 0;
3948 }
3949
3950 void  mux_ipc_enable(__u8 is_enable)
3951 {
3952         int j;
3953         struct sprd_mux *self;
3954
3955         printk(KERN_INFO "MUX: %s entered enable = %d\n", __FUNCTION__, is_enable);
3956
3957         for (j = 0; j <sizeof(sprd_mux_mgr)/sizeof(sprd_mux_mgr[0]); j++) {
3958                 if (sprd_mux_mgr[j].handle) {
3959                         self = sprd_mux_mgr[j].handle;
3960
3961                         MUX_TS0710_DEBUG(self->mux_id, "enable = %d old state = %d\n", is_enable, self->mux_status);
3962
3963                         if (is_enable) {
3964                                 if (self->mux_status == MUX_STATE_NOT_READY) {
3965                                         self->mux_status = MUX_STATE_READY;
3966                                         wake_up_all(&self->modem_ready);
3967                                 } else if (self->mux_status == MUX_STATE_CRASHED) {
3968                                         mux_recover(self);
3969                                 } else {
3970                                         printk(KERN_ERR "MUX: %s wrong enable state \n", __FUNCTION__);
3971                                 }
3972                         } else {
3973                                 if (self->mux_status == MUX_STATE_NOT_READY) {
3974                                         ;//TODO:
3975                                 } else {
3976                                         mux_stop(self);
3977                                 }
3978                         }
3979                 }
3980         }
3981 }
3982
3983 static void mux_wakeup_all_read(struct sprd_mux *self)
3984 {
3985         int j;
3986         mux_recv_struct *recv_info;
3987
3988         if (!self) {
3989                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
3990                 return ;
3991         }
3992
3993         for (j = 0; j < NR_MUXS; j++) {
3994                 if (!(self->mux_recv_info_flags[j])) {
3995                         continue;
3996                 }
3997
3998                 recv_info = self->mux_recv_info[j];
3999                 if (!recv_info) {
4000                         continue;
4001                 }
4002
4003                 wake_up_interruptible(&recv_info->rx_wait);
4004         }
4005 }
4006
4007 static void mux_wakeup_all_write(struct sprd_mux *self)
4008 {
4009         int j;
4010         mux_send_struct *send_info;
4011
4012         if (!self) {
4013                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4014                 return ;
4015         }
4016
4017         for (j = 0; j < NR_MUXS; j++) {
4018                 if (!(self->mux_send_info_flags[j])) {
4019                         continue;
4020                 }
4021
4022                 send_info = self->mux_send_info[j];
4023                 if (!send_info) {
4024                         continue;
4025                 }
4026
4027                 wake_up_interruptible(&send_info->tx_wait);
4028         }
4029
4030 }
4031
4032 static void mux_wakeup_all_opening(struct sprd_mux *self)
4033 {
4034         int j;
4035         ts0710_con *ts0710;
4036
4037         if (!self) {
4038                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4039                 return ;
4040         }
4041
4042         ts0710 = self->connection;
4043
4044         if (!ts0710) {
4045                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
4046                 return;
4047         }
4048
4049         for (j = 0; j < TS0710_MAX_CHN; j++) {
4050                 if (ts0710->dlci[j].state == CONNECTING) {
4051                         wake_up_interruptible(&ts0710->dlci[j].open_wait);
4052                 }
4053         }
4054 }
4055
4056 static void mux_wakeup_all_closing(struct sprd_mux *self)
4057 {
4058         int j;
4059         ts0710_con *ts0710;
4060
4061         if (!self) {
4062                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4063                 return ;
4064         }
4065
4066         ts0710 = self->connection;
4067
4068         if (!ts0710) {
4069                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
4070                 return;
4071         }
4072
4073         for (j = 0; j < TS0710_MAX_CHN; j++) {
4074                 if (ts0710->dlci[j].state == DISCONNECTING) {
4075                         wake_up_interruptible(&ts0710->dlci[j].close_wait);
4076                 }
4077         }
4078 }
4079
4080 static void mux_wakeup_all_wait(struct sprd_mux *self)
4081 {
4082         mux_wakeup_all_read(self);
4083         mux_wakeup_all_write(self);
4084         mux_wakeup_all_opening(self);
4085         mux_wakeup_all_closing(self);
4086
4087         if (self && self->connection) {
4088                 wake_up_interruptible(&self->connection->test_wait);
4089         }
4090 }
4091
4092 static void mux_tidy_buff(struct sprd_mux *self)
4093 {
4094         int j;
4095         int k;
4096         mux_send_struct *send_info;
4097
4098         if (!self) {
4099                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4100                 return ;
4101         }
4102
4103         for (j = 0; j < NR_MUXS; j++) {
4104                 if (!(self->mux_send_info_flags[j])) {
4105                         continue;
4106                 }
4107
4108                 send_info = self->mux_send_info[j];
4109                 if (!send_info) {
4110                         continue;
4111                 }
4112
4113                 for (k = 0; k < ringbuf_num[self->mux_id][j]; k++) {
4114                         send_info->length[k] = 0;
4115                 }
4116
4117                 send_info->read_index = 0;
4118                 send_info->write_index = 0;
4119         }
4120
4121         memset(self->tbuf, 0, TS0710MUX_MAX_BUF_SIZE);
4122         self->tbuf_ptr = self->tbuf;
4123         self->start_flag = 0;
4124         self->framelen = -1;
4125
4126         return;
4127 }
4128
4129 static void mux_recover(struct sprd_mux *self)
4130 {
4131         if (!self) {
4132                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4133                 return;
4134         }
4135
4136         MUX_TS0710_DEBUG(self->mux_id, "entered\n");
4137
4138         self->mux_status = MUX_STATE_RECOVERING;
4139
4140         if (self->mux_recover_kthread) {
4141                 kthread_stop(self->mux_recover_kthread);
4142                 schedule();
4143                 self->mux_recover_kthread = NULL;
4144         }
4145
4146         self->mux_recover_kthread = kthread_create(mux_recover_thread, self, "mux_recover");
4147
4148         if(IS_ERR(self->mux_recover_kthread)) {
4149                 printk(KERN_ERR "MUX: Error %s Unable to create mux_recover_kthread thread err = %ld\n", __FUNCTION__, PTR_ERR(self->mux_recover_kthread));
4150
4151         }
4152
4153         mux_tidy_buff(self);
4154
4155         wake_up_process(self->mux_recover_kthread);
4156 }
4157
4158 static int mux_recover_thread(void *data)
4159 {
4160         struct sprd_mux *self = data;
4161
4162         if (!self) {
4163                 printk(KERN_ERR "MUX: %s self is NULL\n", __FUNCTION__);
4164                 return 0;
4165         }
4166
4167         printk(KERN_ERR "MUX: id[%d] %s entered\n", self->mux_id, __FUNCTION__);
4168
4169         if (self->cmux_mode == 0) {
4170                 mutex_lock(&self->handshake_mutex);
4171                 if (mux_handshake(self) != 0) {
4172                         printk(KERN_ERR "MUX: id[%d] %s handshake fail\n", self->mux_id, __FUNCTION__);
4173                         mutex_unlock(&self->handshake_mutex);
4174                         self->mux_recover_kthread = NULL;
4175                         return 0;
4176                 }
4177
4178                 self->cmux_mode = 1;
4179                 wake_up(&self->handshake_ready);
4180                 mutex_unlock(&self->handshake_mutex);
4181                 while(!kthread_should_stop()) {
4182                          if (mux_restore_channel(self->connection) == 0) {
4183                                 self->mux_status = MUX_STATE_READY;
4184
4185                                 wake_up_all(&self->modem_ready);
4186                                 mux_wakeup_all_read(self);
4187                                 mux_wakeup_all_write(self);
4188                                 self->mux_recover_kthread = NULL;
4189                                 printk(KERN_ERR "MUX: id[%d] %s recover successed\n", self->mux_id, __FUNCTION__);
4190                                 break;
4191                          } else {
4192                                 if (self->mux_status == MUX_STATE_CRASHED) {
4193                                         //another CP disable occured
4194                                         printk(KERN_ERR "MUX: id[%d] %s out anoter disable occured\n", self->mux_id, __FUNCTION__);
4195                                         break;
4196                                 }
4197                                 printk(KERN_ERR "MUX: id[%d] %s recover failed retry\n", self->mux_id, __FUNCTION__);
4198                                 msleep(500);
4199                          }
4200                 }
4201         }
4202
4203         printk(KERN_ERR "MUX: id[%d] %s out\n", self->mux_id, __FUNCTION__);
4204
4205         return 0;
4206 }
4207
4208 static void mux_stop(struct sprd_mux *self)
4209 {
4210         if (!self) {
4211                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4212                 return;
4213         }
4214
4215         MUX_TS0710_DEBUG(self->mux_id, "entered\n");
4216
4217         self->mux_status = MUX_STATE_CRASHED;
4218         self->cmux_mode = 0;
4219         self->io_hal->io_stop(SPRDMUX_ALL);
4220
4221 //      mux_wakeup_all_read(self);
4222 //      mux_wakeup_all_write(self);
4223         mux_wakeup_all_opening(self);
4224         mux_wakeup_all_closing(self);
4225
4226         if (self->connection) {
4227                 wake_up_interruptible(&self->connection->test_wait);
4228         }
4229
4230         if (self->mux_recover_kthread) {
4231                 kthread_stop(self->mux_recover_kthread);
4232                 schedule();
4233                 self->mux_recover_kthread = NULL;
4234         }
4235
4236         return;
4237 }
4238
4239 static void mux_wakeup_channel(ts0710_con * ts0710)
4240 {
4241         __u8 j;
4242
4243         if (!ts0710) {
4244                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
4245                 return;
4246         }
4247
4248         for (j = 0; j < TS0710_MAX_CHN; j++) {
4249                 if (ts0710->dlci[j].state == CONNECTING) {
4250                         wake_up_interruptible(&ts0710->dlci[j].open_wait);
4251                 }
4252         }
4253
4254         for (j = 0; j < TS0710_MAX_CHN; j++) {
4255                 if (ts0710->dlci[j].state == DISCONNECTING) {
4256                         wake_up_interruptible(&ts0710->dlci[j].close_wait);
4257                 }
4258         }
4259 }
4260
4261 static int mux_restore_channel(ts0710_con * ts0710)
4262 {
4263         __u8 j;
4264         __u8 line;
4265         struct sprd_mux *self = NULL;
4266
4267         if (!ts0710) {
4268                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
4269                 return -1;
4270         }
4271
4272         self = (struct sprd_mux *)ts0710->user_data;
4273         if (!self) {
4274                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4275                 return -1;
4276         }
4277
4278         mux_display_connection(ts0710, "before restore");
4279
4280         if (ts0710_ctrl_channel_status(self->connection) != 0) {
4281                 printk(KERN_ERR "MUX: Error %s ctrl channel status is Not OK\n", __FUNCTION__);
4282                 return -1;
4283         }
4284
4285         for (j = 0; j < TS0710_MAX_CHN; j++) {
4286                 line = dlci2line[j].dataline;
4287                 if (ts0710->dlci[j].state == CONNECTING ||
4288                         ts0710->dlci[j].state == NEGOTIATING||
4289                         ts0710->dlci[j].state == CONNECTED ||
4290                         self->open_count[line] != 0) {
4291                         ts0710->dlci[j].state = DISCONNECTED;
4292                         if (ts0710_open_channel(ts0710, j) != 0) {
4293                                 printk(KERN_ERR "MUX: Error %s failed\n", __FUNCTION__);
4294                                 return -1;
4295                         }
4296                 }
4297         }
4298
4299         mux_display_connection(ts0710, "after restore");
4300
4301         return 0;
4302 }
4303
4304 static void mux_display_connection(ts0710_con * ts0710, const char *tag)
4305 {
4306 #ifdef TS0710DEBUG
4307                 __u8 j;
4308                 struct sprd_mux *self = NULL;
4309
4310                 if (!ts0710) {
4311                         printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
4312                         return;
4313                 }
4314
4315                 self = (struct sprd_mux *)ts0710->user_data;
4316                 if (!self) {
4317                         printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4318                         return;
4319                 }
4320
4321                 for (j = 0; j < TS0710_MAX_CHN; j++) {
4322                         printk(KERN_ERR "MUX: %s id[%d] dlci[%d]'s state = %d\n", tag, self->mux_id, j, ts0710->dlci[j].state);
4323                 }
4324 #endif
4325         return;
4326 }
4327
4328 static void mux_init_timer(struct sprd_mux *self)
4329 {
4330         if (!self) {
4331                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4332                 return;
4333         }
4334
4335         init_timer(&self->watch_timer);
4336 }
4337
4338 static void mux_start_timer(struct sprd_mux *self)
4339 {
4340         if (!self) {
4341                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4342                 return;
4343         }
4344
4345         self->watch_timer.expires = jiffies + MUX_WATCH_INTERVAL;
4346         self->watch_timer.data = (unsigned long)self;
4347         self->watch_timer.function = mux_wathch_check;
4348
4349         add_timer(&self->watch_timer);
4350 }
4351
4352 static void mux_wathch_check(unsigned long priv)
4353 {
4354         struct sprd_mux *self = (struct sprd_mux *) priv;
4355
4356         if (!self) {
4357                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4358                 return;
4359         }
4360
4361         printk(KERN_ERR "MUX: %s called\n", __FUNCTION__);
4362
4363         if (self->cmux_mode == 0) {
4364                 self->io_hal->io_stop(self->mux_id);
4365         }
4366 }
4367
4368 static void mux_stop_timer(struct sprd_mux *self)
4369 {
4370         if (!self) {
4371                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4372                 return;
4373         }
4374
4375         del_timer(&self->watch_timer);
4376 }
4377
4378 static int ts0710_ctrl_channel_status(ts0710_con * ts0710)
4379 {
4380         int retval = -ENODEV;
4381         struct sprd_mux *self = NULL;
4382
4383         if (!ts0710) {
4384                 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
4385                 return retval;
4386         }
4387
4388         self = (struct sprd_mux *)ts0710->user_data;
4389         if (!self) {
4390                 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4391                 return retval;
4392         }
4393
4394         if (ts0710->dlci[0].state != CONNECTED) {
4395                 mutex_lock(&self->handshake_mutex);
4396                 if (ts0710->dlci[0].state != CONNECTED) {
4397                         if ((retval = ts0710_open_channel(ts0710, 0)) != 0) {
4398                                 printk(KERN_ERR "MUX: Error Can't connect server channel 0!\n");
4399                                 ts0710_init(ts0710);
4400                                 mutex_unlock(&self->handshake_mutex);
4401                                 return retval;
4402                         }
4403                 }
4404                 mutex_unlock(&self->handshake_mutex);
4405         }
4406
4407         return 0;
4408 }
4409
4410 static void display_send_info(char * tag, SPRDMUX_ID_E mux_id, int line)
4411 {
4412         struct sprd_mux *self = NULL;
4413         mux_send_struct *send_info;
4414         int j;
4415         self = sprd_mux_mgr[mux_id].handle;
4416
4417         if (!self) {
4418                 printk(KERN_ERR "MUX: %s, %s mux[%d] line[%d] pid[%d] self  NULL\n", tag, __FUNCTION__, mux_id, line, current->pid);
4419                 return;
4420         }
4421
4422         send_info = self->mux_send_info[line];
4423
4424         if (!send_info) {
4425                 printk(KERN_ERR "MUX: %s, %s mux[%d] line[%d] pid[%d] send_info  NULL\n", tag, __FUNCTION__, mux_id, line, current->pid);
4426                 return;
4427         }
4428
4429         if (!send_info->frame) {
4430                 printk(KERN_ERR "MUX: %s, %s mux[%d] line[%d] pid[%d] send_info->frame  NULL\n", tag, __FUNCTION__, mux_id, line, current->pid);
4431                 return;
4432         }
4433
4434         if (!send_info->buf) {
4435                 printk(KERN_ERR "MUX: %s, %s mux[%d] line[%d] pid[%d] send_info->buf  NULL\n", tag, __FUNCTION__, mux_id, line, current->pid);
4436                 return;
4437         }
4438
4439         if (!send_info->length) {
4440                 printk(KERN_ERR "MUX: %s, %s mux[%d] line[%d] pid[%d] send_info->length  NULL\n", tag, __FUNCTION__, mux_id, line, current->pid);
4441                 return;
4442         }
4443
4444 //      printk(KERN_ERR "MUX: %s, %s mux[%d] line[%d] buf = 0x%x, frame = 0x%x, length = 0x%x\n", tag, __FUNCTION__, mux_id, line, send_info->buf, send_info->frame, send_info->length);
4445
4446         for (j = 0; j < ringbuf_num[mux_id][line]; j++) {
4447 //              printk(KERN_ERR "MUX: %s, %s mux[%d] line[%d] index[%d] send_info->length[%d] = %u send_info->frame[%d] = 0x%u\n", tag, __FUNCTION__, mux_id, line, j,  send_info->length[j], j,send_info->frame[j]);
4448         }
4449 }
4450
4451
4452
4453 EXPORT_SYMBOL(sprdmux_register);
4454 EXPORT_SYMBOL(sprdmux_unregister);
4455 EXPORT_SYMBOL(sprdmux_open);
4456 EXPORT_SYMBOL(sprdmux_close);
4457 EXPORT_SYMBOL(sprdmux_write);
4458 EXPORT_SYMBOL(sprdmux_register_notify_callback);
4459 EXPORT_SYMBOL(sprdmux_line_busy);
4460 EXPORT_SYMBOL(sprdmux_set_line_notify);
4461
4462 EXPORT_SYMBOL(ts0710_mux_create);
4463 EXPORT_SYMBOL(ts0710_mux_destory);
4464 EXPORT_SYMBOL(ts0710_mux_init);
4465 EXPORT_SYMBOL(ts0710_mux_exit);
4466 EXPORT_SYMBOL(ts0710_mux_status);
4467 EXPORT_SYMBOL(ts0710_mux_open);
4468 EXPORT_SYMBOL(ts0710_mux_close);
4469 EXPORT_SYMBOL(ts0710_mux_write);
4470 EXPORT_SYMBOL(ts0710_mux_read);
4471 EXPORT_SYMBOL(ts0710_mux_poll_wait);
4472 EXPORT_SYMBOL(ts0710_mux_mux_ioctl);
4473
4474 MODULE_LICENSE("GPL");
4475 MODULE_AUTHOR("Harald Welte <laforge@openezx.org>");
4476 MODULE_DESCRIPTION("GSM TS 07.10 Multiplexer");
4477