3 * Portions derived from rfcomm.c, original header as follows:
5 * Copyright (C) 2000, 2001 Axis Communications AB
7 * Author: Mats Friden <mats.friden@axis.com>
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.
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.
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.
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.
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.
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.
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
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>
73 #include "ts0710_mux.h"
76 #define TS0710MUX_GPRS_SESSION_MAX 3
77 #define TS0710MUX_MAJOR 250
78 #define TS0710MUX_MINOR_START 0
81 #define TS0710MUX_TIME_OUT 250 /* 2500ms, for BP UART hardware flow control AP UART */
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
88 #define TS0710MUX_MAX_BUF_SIZE (64*1024)
89 #define TS0710MUX_MAX_TOTAL_SIZE (1024*1024)
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
95 /*For BP UART problem Begin*/
97 #define ACK_SPACE 0 /* 6 * 11(ACK frame size) */
99 #define ACK_SPACE 0 /* 6 * 7(ACK frame size) */
101 /*For BP UART problem End*/
103 #define TS0710MUX_SERIAL_BUF_SIZE (DEF_TS0710_MTU + TS0710_MAX_HDR_SIZE + ACK_SPACE) /* For BP UART problem: ACK_SPACE */
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
109 #define TEST_PATTERN_SIZE 250
114 #define ACK 0x4F /*For BP UART problem */
116 /*For BP UART problem Begin*/
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
125 #define SLIDE_BP_SEQ_OFFSET 1 /*offset from start flag */
126 #define SEQ_FIELD_SIZE 0
129 #define ADDRESS_FIELD_OFFSET (1 + SEQ_FIELD_SIZE) /*offset from start flag */
130 /*For BP UART problem End*/
133 #define UNUSED_PARAM(v) (void)(v)
136 #define TS0710MUX_GPRS1_DLCI 3
137 #define TS0710MUX_GPRS2_DLCI 4
138 #define TS0710MUX_VT_DLCI 2
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
147 #define TS0710MUX_COUNT_MAX_IDX 5
148 #define TS0710MUX_COUNT_IDX_NUM (TS0710MUX_COUNT_MAX_IDX + 1)
150 #define SPRDMUX_MAX_NUM SPRDMUX_ID_MAX
152 /* Bit number in flags of mux_send_struct */
153 #define RECV_RUNNING 0
154 #define MUX_MODE_MAX_LEN 11
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
161 #define MUX_RIL_LINE_END 11
163 #define MUX_VETH_LINE_BEGIN 13
164 #define MUX_VETH_LINE_END 17
165 #define MUX_VETH_RINGBUFER_NUM 24
167 #define MUX_WATCH_INTERVAL 3 * HZ
170 //#define TS0710DEBUG
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};
181 static dlci_line dlci2line[] = {
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 */
217 /* set line ring buffer num*/
218 static __u8 ringbuf_num[SPRDMUX_ID_MAX][NR_MUXS];
227 volatile __u8 dummy; /* Allignment to 4*n bytes */
228 struct mutex send_lock;
229 // struct mutex send_data_lock; /*Todo*/
233 wait_queue_head_t tx_wait;
236 struct mux_recv_packet_tag {
240 struct mux_recv_packet_tag *next;
242 typedef struct mux_recv_packet_tag mux_recv_packet;
244 struct mux_recv_struct_tag {
245 __u8 data[TS0710MUX_RECV_BUF_SIZE];
249 mux_recv_packet *mux_packet;
250 struct mutex recv_lock;
251 struct mutex recv_data_lock;
252 wait_queue_head_t rx_wait;
254 typedef struct mux_recv_struct_tag mux_recv_struct;
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;
270 struct task_struct *mux_recv_kthread;
271 struct task_struct *mux_send_kthread;
273 struct sprdmux *io_hal;
274 ts0710_con *connection;
275 volatile int cmux_mode;
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];
282 __u32 check_read_sum[NR_MUXS];
283 __u32 check_write_sum[NR_MUXS];
285 wait_queue_head_t handshake_ready;
286 wait_queue_head_t modem_ready;
287 struct task_struct *mux_recover_kthread;
291 unsigned char tbuf[TS0710MUX_MAX_BUF_SIZE];
292 unsigned char *tbuf_ptr;
293 unsigned char *start_flag;
295 /*For BP UART problem Begin */
297 /*For BP UART problem End */
298 struct timer_list watch_timer;
301 unsigned char debug_hex_buf[TS0710MUX_MAX_BUF_SIZE];
302 unsigned char debug_str_buf[TS0710MUX_MAX_BUF_SIZE];
306 unsigned char debug_frame_buf[TS0710MUX_MAX_BUF_SIZE];
311 typedef struct mux_info_{
313 char mux_name[SPRDMUX_MAX_NAME_LEN];
314 struct sprd_mux *handle;
319 static mux_info sprd_mux_mgr[SPRDMUX_MAX_NUM] =
322 .mux_id = SPRDMUX_ID_SPI,
323 .mux_name = "spimux",
327 .mux_id = SPRDMUX_ID_SDIO,
328 .mux_name = "sdiomux",
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;
342 #define min(a,b) ( (a)<(b) ? (a):(b) )
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];
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);
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);
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);
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);
391 #define TS0710_DEBUG(fmt, arg...) printk(KERN_INFO "MUX:%s "fmt, __FUNCTION__ , ## arg)
392 #define MUX_TS0710_DEBUG(mux_id, fmt, arg...) \
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); \
398 #define TS0710_DEBUG(fmt...)
399 #define MUX_TS0710_DEBUG(mux_id, fmt, arg...)
400 #endif /* End #ifdef TS0710DEBUG */
403 #define TS0710_PRINTK(fmt, arg...) printk(fmt, ## arg)
405 #define TS0710_PRINTK(fmt, arg...) printk(fmt, ## arg)
406 #endif /* End #ifdef TS0710LOG */
409 static void MUX_TS0710_DEBUGHEX(SPRDMUX_ID_E mux_id, __u8 * buf, int len)
411 unsigned char *tbuf = NULL;
415 if (mux_id < 0 || mux_id >= SPRDMUX_ID_MAX || !buf || len <= 0) {
416 printk(KERN_ERR "MUX: Error %s Invalid Param\n", __FUNCTION__);
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__);
426 tbuf = sprd_mux_mgr[mux_id].handle->debug_hex_buf;
429 printk(KERN_ERR "MUX[%d]: Error %s mux_id tbuf is NULL\n", mux_id, __FUNCTION__);
433 for (i = 0; (i < len) && (c < (TS0710MUX_MAX_BUF_SIZE - 3)); i++) {
434 sprintf(&tbuf[c], "%02x ", buf[i]);
439 MUX_TS0710_DEBUG(mux_id, "%s", tbuf);
442 static void MUX_TS0710_DEBUGSTR(SPRDMUX_ID_E mux_id, __u8 * buf, int len)
444 unsigned char *tbuf = NULL;
445 struct sprd_mux *self = NULL;
447 if (mux_id < 0 || mux_id >= SPRDMUX_ID_MAX || !buf || len <= 0) {
448 printk(KERN_ERR "MUX: Error %s Invalid Param\n", __FUNCTION__);
452 self = sprd_mux_mgr[mux_id].handle;
454 printk(KERN_ERR "MUX[%d]: Error %s self is NULL\n", mux_id, __FUNCTION__);
459 tbuf = self->debug_str_buf;
462 printk(KERN_ERR "MUX[%d]: Error %s mux_id tbuf is NULL\n", mux_id, __FUNCTION__);
466 if (len > (TS0710MUX_MAX_BUF_SIZE - 1)) {
467 len = (TS0710MUX_MAX_BUF_SIZE - 1);
470 memcpy(tbuf, buf, len);
473 /* 0x00 byte in the string pointed by tbuf may truncate the print result */
474 MUX_TS0710_DEBUG(mux_id, "%s", tbuf);
477 #define MUX_TS0710_DEBUGHEX(mux_id, buf, len)
478 #define MUX_TS0710_DEBUGSTR(mux_id, buf, len)
479 #endif /* End #ifdef TS0710DEBUG */
482 static void MUX_TS0710_LOGSTR_FRAME(SPRDMUX_ID_E mux_id, __u8 send, __u8 * data, int len)
484 unsigned char *tbuf = NULL;
485 short_frame *short_pkt;
486 long_frame *long_pkt;
487 __u8 *uih_data_start;
491 struct sprd_mux *self = NULL;
493 if (mux_id < 0 || mux_id >= SPRDMUX_ID_MAX || !data || len <= 0) {
494 printk(KERN_ERR "MUX: Error %s Invalid Param\n", __FUNCTION__);
498 self = sprd_mux_mgr[mux_id].handle;
500 printk(KERN_ERR "MUX[%d]: Error %s self is NULL\n", mux_id, __FUNCTION__);
504 tbuf = self->debug_frame_buf;
507 printk(KERN_ERR "MUX[%d]: Error %s tbuf is NULL\n", mux_id, __FUNCTION__);
517 pos += sprintf(&tbuf[pos], "<");
518 short_pkt = (short_frame *) (data + 1);
521 sprintf(&tbuf[pos], ">%d ",
522 *(data + SLIDE_BP_SEQ_OFFSET));
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));
533 short_pkt = (short_frame *) (data + ADDRESS_FIELD_OFFSET);
536 dlci = short_pkt->h.addr.server_chn << 1 | short_pkt->h.addr.d;
537 switch (CLR_PF(short_pkt->h.control)) {
539 pos += sprintf(&tbuf[pos], "C SABM %d ::", dlci);
542 pos += sprintf(&tbuf[pos], "C UA %d ::", dlci);
545 pos += sprintf(&tbuf[pos], "C DM %d ::", dlci);
548 pos += sprintf(&tbuf[pos], "C DISC %d ::", dlci);
552 pos += sprintf(&tbuf[pos], "C ACK %d ", short_pkt->data[0]);
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]);
561 pos += sprintf(&tbuf[pos], "::");
566 pos += sprintf(&tbuf[pos], "C MCC %d ::", dlci);
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;
574 uih_len = short_pkt->h.length.len;
575 uih_data_start = short_pkt->data;
580 sprintf(&tbuf[pos], "I %d A %d ::", dlci,
586 sprintf(&tbuf[pos], "I %d D %d ::", dlci,
594 pos += sprintf(&tbuf[pos], "N!!! %d ::", dlci);
598 if (len > (TS0710MUX_MAX_BUF_SIZE - pos - 1)) {
599 len = (TS0710MUX_MAX_BUF_SIZE - pos - 1);
602 memcpy(&tbuf[pos], data, len);
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);
610 #define MUX_TS0710_LOGSTR_FRAME(mux_id, send, data, len)
614 #define my_for_each_task(p) \
615 for ((p) = current; ((p) = (p)->next_task) != current; )
618 static void TS0710_SIG2APLOGD(void)
620 struct task_struct *p;
627 read_lock(&tasklist_lock);
628 my_for_each_task(p) {
629 if (strncmp(p->comm, "aplogd", 6) == 0) {
631 if (send_sig(SIGUSR2, p, 1) == 0) {
633 ("MUX: success to send SIGUSR2 to aplogd!\n");
636 ("MUX: failure to send SIGUSR2 to aplogd!\n");
641 read_unlock(&tasklist_lock);
644 TS0710_PRINTK("MUX: not found aplogd!\n");
648 #define TS0710_SIG2APLOGD()
651 static int valid_dlci(__u8 dlci)
653 if ((dlci < TS0710_MAX_CHN) && (dlci > 0))
659 static int basic_write(ts0710_con * ts0710, __u8 * buf, int len)
662 struct sprd_mux *self = NULL;
665 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
669 self = (struct sprd_mux *)ts0710->user_data;
671 if (!self || !self->io_hal || !self->io_hal->io_write) {
672 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
676 buf[0] = TS0710_BASIC_FLAG;
677 buf[len + 1] = TS0710_BASIC_FLAG;
679 MUX_TS0710_LOGSTR_FRAME(self->mux_id, 1, buf, len + 2);
680 MUX_TS0710_DEBUGHEX(self->mux_id, buf, len + 2);
683 while (send < len + 2) {
684 res = self->io_hal->io_write(buf + send, len + 2 - send);
696 /* Functions for the crc-check and calculation */
698 #define CRC_VALID 0xcf
700 static __u32 crc_check(__u8 * data, __u32 length, __u8 check_sum)
708 fcs = crctable[fcs ^ *data++];
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,
714 if (fcs == (uint) 0xcf) { /*CRC_VALID) */
715 TS0710_DEBUG("crc_check: CRC check OK\n");
718 TS0710_PRINTK("MUX crc_check: CRC check failed\n");
723 /* Calculates the checksum according to the ts0710 specification */
725 static __u8 crc_calc(__u8 * data, __u32 length)
730 fcs = crctable[fcs ^ *data++];
736 /* Calulates a reversed CRC table for the FCS check */
738 static void create_crctable(__u8 table[])
743 __u8 code_word = (__u8) 0xe0;
746 for (j = 0; j < 256; j++) {
749 for (i = 0; i < 8; i++) {
750 if ((data & 0x1) ^ (sr & 0x1)) {
766 static void ts0710_reset_dlci(ts0710_con *ts0710, __u8 j)
768 if (j >= TS0710_MAX_CHN)
772 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
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;
783 static void ts0710_reset_con(ts0710_con *ts0710)
788 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
792 ts0710->initiator = 0;
793 ts0710->mtu = DEF_TS0710_MTU + TS0710_MAX_HDR_SIZE;
794 ts0710->be_testing = 0;
795 ts0710->test_errs = 0;
797 for (j = 0; j < TS0710_MAX_CHN; j++) {
798 ts0710_reset_dlci(ts0710, j);
802 static void ts0710_init_waitqueue(ts0710_con *ts0710)
807 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
811 init_waitqueue_head(&ts0710->test_wait);
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);
819 static void ts0710_init(ts0710_con *ts0710)
822 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
826 ts0710_reset_con(ts0710);
829 static void ts0710_upon_disconnect(ts0710_con *ts0710)
834 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
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);
843 ts0710->be_testing = 0;
844 wake_up_interruptible(&ts0710->test_wait);
845 ts0710_reset_con(ts0710);
848 /* Sending packet functions */
850 /* Creates a UA packet and puts it at the beginning of the pkt pointer */
852 static int send_ua(ts0710_con * ts0710, __u8 dlci)
854 __u8 buf[sizeof(short_frame) + FCS_SIZE + FLAG_SIZE];
859 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
863 if (!ts0710->user_data) {
864 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
868 MUX_TS0710_DEBUG(((struct sprd_mux *)ts0710->user_data)->mux_id, "send_ua: Creating UA packet to DLCI %d\n", dlci);
870 ua = (short_frame *) (buf + 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);
877 ua->h.length.len = 0;
878 ua->data[0] = crc_calc((__u8 *) ua, SHORT_CRC_CHECK);
880 return basic_write(ts0710, buf, sizeof(short_frame) + FCS_SIZE);
883 /* Creates a DM packet and puts it at the beginning of the pkt pointer */
885 static int send_dm(ts0710_con * ts0710, __u8 dlci)
887 __u8 buf[sizeof(short_frame) + FCS_SIZE + FLAG_SIZE];
891 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
895 if (!ts0710->user_data) {
896 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
900 MUX_TS0710_DEBUG(((struct sprd_mux *)ts0710->user_data)->mux_id, "send_dm: Creating DM packet to DLCI %d\n", dlci);
902 dm = (short_frame *) (buf + 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);
909 dm->h.length.len = 0;
910 dm->data[0] = crc_calc((__u8 *) dm, SHORT_CRC_CHECK);
912 return basic_write(ts0710, buf, sizeof(short_frame) + FCS_SIZE);
915 static int send_sabm(ts0710_con * ts0710, __u8 dlci)
917 __u8 buf[sizeof(short_frame) + FCS_SIZE + FLAG_SIZE];
921 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
925 if (!ts0710->user_data) {
926 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
930 MUX_TS0710_DEBUG(((struct sprd_mux *)ts0710->user_data)->mux_id, "send_sabm: Creating SABM packet to DLCI %d\n", dlci);
932 sabm = (short_frame *) (buf + 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);
942 return basic_write(ts0710, buf, sizeof(short_frame) + FCS_SIZE);
945 static int send_disc(ts0710_con * ts0710, __u8 dlci)
947 __u8 buf[sizeof(short_frame) + FCS_SIZE + FLAG_SIZE];
952 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
956 if (!ts0710->user_data)
958 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
962 MUX_TS0710_DEBUG(((struct sprd_mux *)ts0710->user_data)->mux_id, "send_disc: Creating DISC packet to DLCI %d\n", dlci);
964 disc = (short_frame *) (buf + 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);
974 return basic_write(ts0710, buf, sizeof(short_frame) + FCS_SIZE);
977 static void queue_uih(mux_send_struct * send_info, __u32 ring_index, __u16 len,
978 ts0710_con * ts0710, __u8 dlci)
982 if (!ts0710 || !send_info) {
983 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
987 if (!ts0710->user_data) {
988 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
992 if (!send_info->frame) {
993 printk(KERN_ERR "MUX: Error %s send_info->frame is NULL\n", __FUNCTION__);
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);
999 if (len > SHORT_PAYLOAD_SIZE) {
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;
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;
1017 if (!send_info->length) {
1018 printk(KERN_ERR "MUX: %s pid[%d] send_info->length NULL\n", __FUNCTION__, current->pid);
1022 send_info->length[ring_index] = size;
1025 /* Multiplexer command packets functions */
1027 /* Turns on the ts0710 flow control */
1029 static int ts0710_fcon_msg(ts0710_con * ts0710, __u8 cr)
1032 mcc_short_frame *mcc_pkt;
1033 short_frame *uih_pkt;
1037 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
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);
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;
1053 return basic_write(ts0710, buf, size);
1056 /* Turns off the ts0710 flow control */
1058 static int ts0710_fcoff_msg(ts0710_con * ts0710, __u8 cr)
1061 mcc_short_frame *mcc_pkt;
1062 short_frame *uih_pkt;
1066 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
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);
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;
1082 return basic_write(ts0710, buf, size);
1085 /* Sends an PN-messages and sets the not negotiable parameters to their
1086 default values in ts0710 */
1088 static int send_pn_msg(ts0710_con * ts0710, __u8 prior, __u32 frame_size,
1089 __u8 credit_flow, __u8 credits, __u8 dlci, __u8 cr)
1097 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
1101 if (!ts0710->user_data) {
1102 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
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);
1110 size = sizeof(pn_msg);
1111 pn_pkt = (pn_msg *) (buf + 1);
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);
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;
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;
1133 return basic_write(ts0710, buf, size);
1136 /* Send a Not supported command - command, which needs 3 bytes */
1138 static int send_nsc_msg(ts0710_con * ts0710, mcc_type cmd, __u8 cr)
1144 size = sizeof(nsc_msg);
1145 nsc_pkt = (nsc_msg *) (buf + 1);
1148 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
1152 set_uih_hdr((void *)nsc_pkt, CTRL_CHAN, sizeof(nsc_msg) - sizeof(short_frame) - FCS_SIZE, ts0710->initiator);
1154 nsc_pkt->fcs = crc_calc((__u8 *) nsc_pkt, SHORT_CRC_CHECK);
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;
1162 nsc_pkt->command_type.ea = 1;
1163 nsc_pkt->command_type.cr = cmd.cr;
1164 nsc_pkt->command_type.type = cmd.type;
1166 return basic_write(ts0710, buf, size);
1169 static int ts0710_msc_msg(ts0710_con * ts0710, __u8 value, __u8 cr, __u8 dlci)
1175 size = sizeof(msc_msg);
1176 msc_pkt = (msc_msg *) (buf + 1);
1179 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
1183 set_uih_hdr((void *)msc_pkt, CTRL_CHAN, sizeof(msc_msg) - sizeof(short_frame) - FCS_SIZE, ts0710->initiator);
1185 msc_pkt->fcs = crc_calc((__u8 *) msc_pkt, SHORT_CRC_CHECK);
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;
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;
1198 msc_pkt->v24_sigs = value;
1200 return basic_write(ts0710, buf, size);
1203 static int ts0710_test_msg(ts0710_con * ts0710, __u8 * test_pattern, __u32 len,
1204 __u8 cr, __u8 * f_buf)
1208 if (!ts0710 || !test_pattern || !f_buf)
1210 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
1214 if (len > SHORT_PAYLOAD_SIZE) {
1215 long_frame *uih_pkt;
1216 mcc_long_frame *mcc_pkt;
1218 size = (sizeof(long_frame) + sizeof(mcc_long_frame) + len + FCS_SIZE);
1219 uih_pkt = (long_frame *) (f_buf + 1);
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;
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;
1235 /* Create long uih packet and short mcc packet */
1237 (sizeof(long_frame) + sizeof(mcc_short_frame) + len +
1239 uih_pkt = (long_frame *) (f_buf + 1);
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;
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);
1252 short_frame *uih_pkt;
1253 mcc_short_frame *mcc_pkt;
1255 size = (sizeof(short_frame) + sizeof(mcc_short_frame) + len + FCS_SIZE);
1256 uih_pkt = (short_frame *) (f_buf + 1);
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;
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);
1272 return basic_write(ts0710, f_buf, size);
1275 static void set_uih_hdr(short_frame * uih_pkt, __u8 dlci, __u32 len, __u8 cr)
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);
1283 if (len > SHORT_PAYLOAD_SIZE) {
1284 SET_LONG_LENGTH(((long_frame *) uih_pkt)->h.length, len);
1286 uih_pkt->h.length.ea = 1;
1287 uih_pkt->h.length.len = len;
1291 /* Parses a multiplexer control channel packet */
1293 static void process_mcc(__u8 * data, __u32 len, ts0710_con * ts0710, int longpkt)
1296 mcc_short_frame *mcc_short_pkt;
1297 struct sprd_mux *self = NULL;
1300 TS0710_DEBUG("process_mcc\n");
1302 if (!ts0710 || !data) {
1303 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
1307 self = (struct sprd_mux *)ts0710->user_data;
1309 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
1314 mcc_short_pkt = (mcc_short_frame *) (((long_frame *) data)->data);
1316 mcc_short_pkt = (mcc_short_frame *) (((short_frame *) data)->data);
1319 switch (mcc_short_pkt->h.type.type) {
1321 if (mcc_short_pkt->h.type.cr == MCC_RSP) {
1322 MUX_TS0710_DEBUG(self->mux_id, "Received test command response\n");
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;
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);
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)++;
1344 #if TEST_PATTERN_SIZE < 128
1345 if (mcc_short_pkt->h.length.len != TEST_PATTERN_SIZE) {
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);
1351 #if TEST_PATTERN_SIZE < 128
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)++;
1364 ts0710->be_testing = 0; /* Clear the flag */
1365 wake_up_interruptible(&ts0710->test_wait);
1367 MUX_TS0710_DEBUG(self->mux_id, "Err: shouldn't or late to get test cmd response\n");
1370 tbuf = (__u8 *) kmalloc(len + 32, GFP_ATOMIC);
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.
1383 ts0710_test_msg(ts0710, mcc_short_pkt->value,
1384 mcc_short_pkt->h.length.len,
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);
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;
1407 ts0710_fcoff_msg(ts0710, MCC_RSP);
1411 case MSC: /*Modem status command */
1416 dlci = (mcc_short_pkt->value[0]) >> 2;
1417 v24_sigs = mcc_short_pkt->value[1];
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);
1425 if (mcc_short_pkt->h.type.cr == MCC_CMD) {
1426 MUX_TS0710_DEBUG(self->mux_id, "Received Modem status command\n");
1428 if (ts0710->dlci[dlci].state ==
1430 MUX_TS0710_DEBUG(self->mux_id, "MUX Received Flow off on dlci %d\n",
1432 ts0710->dlci[dlci].state =
1436 if (ts0710->dlci[dlci].state ==
1438 ts0710->dlci[dlci].state =
1440 MUX_TS0710_DEBUG(self->mux_id, "MUX Received Flow on on dlci %d\n",
1442 mux_sched_send(self);
1446 ts0710_msc_msg(ts0710, v24_sigs, MCC_RSP, dlci);
1449 MUX_TS0710_DEBUG(self->mux_id, "Received Modem status response\n");
1452 MUX_TS0710_DEBUG(self->mux_id, "Flow stop accepted\n");
1458 case PN: /*DLC parameter negotiation */
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);
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);
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);
1484 min(frame_size, ts0710->dlci[dlci].mtu);
1485 ts0710->dlci[dlci].mtu = frame_size;
1487 MUX_TS0710_DEBUG(self->mux_id,
1488 "process_mcc : mtu set on dlci:%d to %d\n",
1489 dlci, ts0710->dlci[dlci].mtu);
1491 if (ts0710->dlci[dlci].state == NEGOTIATING) {
1492 ts0710->dlci[dlci].state = CONNECTING;
1493 wake_up_all(&ts0710->dlci[dlci].open_wait);
1499 case NSC: /*Non supported command resonse */
1500 MUX_TS0710_DEBUG(self->mux_id, "MUX Received Non supported command response\n");
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);
1510 static mux_recv_packet *get_mux_recv_packet(__u32 size)
1512 mux_recv_packet *recv_packet;
1514 recv_packet = (mux_recv_packet *) kmalloc(sizeof(mux_recv_packet), GFP_ATOMIC);
1519 recv_packet->data = (__u8 *) kmalloc(size, GFP_ATOMIC);
1520 if (!(recv_packet->data)) {
1524 recv_packet->length = 0;
1525 recv_packet->next = 0;
1526 recv_packet->pos = 0;
1531 static void free_mux_recv_packet(mux_recv_packet * recv_packet)
1537 if (recv_packet->data) {
1538 kfree(recv_packet->data);
1543 static void free_mux_recv_struct(mux_recv_struct * recv_info)
1545 mux_recv_packet *recv_packet1, *recv_packet2;
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;
1561 static int ts0710_recv_data(ts0710_con * ts0710, char *data, int len)
1563 short_frame *short_pkt;
1564 long_frame *long_pkt;
1565 __u8 *uih_data_start;
1569 struct sprd_mux *self = NULL;
1571 if (!ts0710 || !data) {
1572 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
1576 self = (struct sprd_mux *)ts0710->user_data;
1579 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
1583 short_pkt = (short_frame *) data;
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)) {
1589 MUX_TS0710_DEBUG(self->mux_id, "SABM-packet received\n");
1592 MUX_TS0710_DEBUG(self->mux_id, "server channel == 0\n");
1593 ts0710->dlci[0].state = CONNECTED;
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);
1599 } else if (valid_dlci(dlci)) {
1601 MUX_TS0710_DEBUG(self->mux_id, "Incomming connect on channel %d\n", dlci);
1603 MUX_TS0710_DEBUG(self->mux_id, "sending UA, dlci %d\n", dlci);
1604 send_ua(ts0710, dlci);
1606 ts0710->dlci[dlci].state = CONNECTED;
1607 wake_up_all(&ts0710->dlci[dlci].open_wait);
1610 MUX_TS0710_DEBUG(self->mux_id, "invalid dlci %d, sending DM\n", dlci);
1611 send_dm(ts0710, dlci);
1617 printk(KERN_INFO "MUX: id[%d] dlci = %d UA packet received\n", self->mux_id, dlci);
1620 MUX_TS0710_DEBUG(self->mux_id, "server channel == 0|dlci[0].state=%d\n",
1621 ts0710->dlci[0].state);
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);
1629 MUX_TS0710_DEBUG(self->mux_id, " Something wrong receiving UA packet\n");
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);
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);
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);
1650 printk(KERN_ERR "MUX: id[%d] dlci[%d] wrong receiving UA packet state = %d\n", self->mux_id, dlci, ts0710->dlci[dlci].state);
1653 MUX_TS0710_DEBUG(self->mux_id, "invalid dlci %d\n", dlci);
1659 MUX_TS0710_DEBUG(self->mux_id, "DM packet received\n");
1662 MUX_TS0710_DEBUG(self->mux_id, "server channel == 0\n");
1664 if (ts0710->dlci[0].state == CONNECTING) {
1669 ts0710_upon_disconnect(ts0710);
1670 if (be_connecting) {
1671 ts0710->dlci[0].state = REJECTED;
1673 } else if (valid_dlci(dlci)) {
1674 MUX_TS0710_DEBUG(self->mux_id, "Incomming DM on channel %d\n", dlci);
1676 if (ts0710->dlci[dlci].state == CONNECTING) {
1677 ts0710->dlci[dlci].state = REJECTED;
1679 ts0710->dlci[dlci].state = DISCONNECTED;
1681 wake_up_all(&ts0710->dlci[dlci].open_wait);
1682 wake_up_interruptible(&ts0710->dlci[dlci].close_wait);
1683 ts0710_reset_dlci(ts0710, dlci);
1685 MUX_TS0710_DEBUG(self->mux_id, "invalid dlci %d\n", dlci);
1690 MUX_TS0710_DEBUG(self->mux_id, "DISC packet received\n");
1693 MUX_TS0710_DEBUG(self->mux_id, "server channel == 0\n");
1695 send_ua(ts0710, dlci);
1696 MUX_TS0710_DEBUG(self->mux_id, "DISC, sending back UA\n");
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);
1702 send_ua(ts0710, dlci);
1703 MUX_TS0710_DEBUG(self->mux_id, "DISC, sending back UA\n");
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);
1710 MUX_TS0710_DEBUG(self->mux_id, "invalid dlci %d\n", dlci);
1716 MUX_TS0710_DEBUG(self->mux_id, "UIH packet received\n");
1718 if ((dlci >= TS0710_MAX_CHN)) {
1719 MUX_TS0710_DEBUG(self->mux_id, "invalid dlci %d\n", dlci);
1720 send_dm(ts0710, dlci);
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");
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);
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);
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;
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 */
1757 mux_recv_struct *recv_info;
1759 mux_recv_packet *recv_packet, *recv_packet2;
1760 MUX_TS0710_DEBUG(self->mux_id, "UIH on channel %d\n", dlci);
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);
1768 line = dlci2line[dlci].dataline; /* we see data and commmand as same */
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)) {
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);
1786 recv_info = self->mux_recv_info[line];
1788 MUX_TS0710_DEBUG(self->mux_id, "recv_data : recv_info is null\n");
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);
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);
1802 mutex_lock(&recv_info->recv_data_lock);
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);
1808 MUX_TS0710_DEBUG(self->mux_id, "MUX: no memory\n");
1809 mutex_unlock(&recv_info->recv_data_lock);
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;
1818 recv_packet->next = NULL;
1820 if (!(recv_info->mux_packet)) {
1821 recv_info->mux_packet = recv_packet;
1823 recv_packet2 = recv_info->mux_packet;
1824 while (recv_packet2->next) {
1825 recv_packet2 = recv_packet2->next;
1827 recv_packet2->next = recv_packet;
1828 } /* End if( !(recv_info->mux_packet) ) */
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;
1834 memcpy(recv_info->data, uih_data_start, uih_len);
1835 recv_info->length = uih_len;
1836 recv_info->total = uih_len;
1838 self->check_read_sum[line] += uih_len;
1839 wake_up_interruptible(&recv_info->rx_wait);
1842 mutex_unlock(&recv_info->recv_data_lock);
1843 } /* End processing received data */
1845 MUX_TS0710_DEBUG(self->mux_id, "invalid dlci %d\n", dlci);
1851 MUX_TS0710_DEBUG(self->mux_id, "illegal packet\n");
1857 /* Close ts0710 channel */
1858 static void ts0710_close_channel(ts0710_con *ts0710, __u8 dlci)
1862 struct sprd_mux *self = NULL;
1865 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
1869 self = (struct sprd_mux *)ts0710->user_data;
1872 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
1876 MUX_TS0710_DEBUG(((struct sprd_mux *)ts0710->user_data)->mux_id, "ts0710_disc_command on channel %d\n", dlci);
1878 if ((ts0710->dlci[dlci].state == DISCONNECTED)
1879 || (ts0710->dlci[dlci].state == REJECTED)) {
1881 } else if (ts0710->dlci[dlci].state == DISCONNECTING) {
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;
1896 send_disc(ts0710, dlci);
1897 interruptible_sleep_on_timeout(&ts0710->dlci[dlci].close_wait, 10 * TS0710MUX_TIME_OUT);
1899 if (ts0710->dlci[dlci].state == DISCONNECTED) {
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);
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);
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);
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);
1926 static int ts0710_open_channel(ts0710_con *ts0710, __u8 dlci)
1930 struct sprd_mux *self = NULL;
1935 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
1939 self = (struct sprd_mux *)ts0710->user_data;
1942 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
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);
1948 if (dlci == 0) { /* control channel */
1949 if ((ts0710->dlci[0].state == CONNECTED)
1950 || (ts0710->dlci[0].state == FLOW_STOPPED)) {
1952 } else if (ts0710->dlci[0].state == CONNECTING) {
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);
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);
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);
1967 if ((ts0710->dlci[0].state == CONNECTED)
1968 || (ts0710->dlci[0].state == FLOW_STOPPED)) {
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;
1975 } else if (ts0710->dlci[0].state == DISCONNECTED) {
1976 printk(KERN_ERR "MUX: id[%d] Error DLCI[%d] DISCONNECTED\n", self->mux_id, dlci);
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);
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);
1990 if (ts0710->dlci[0].state == CONNECTING) {
1991 ts0710->dlci[0].state = DISCONNECTED;
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);
1999 ts0710->initiator = 1;
2000 ts0710->dlci[0].state = CONNECTING;
2001 ts0710->dlci[0].initiator = 1;
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);
2009 TS0710_PRINTK("MUX: id[%d] DLCI:%d after open wait state = %d try = %d", self->mux_id, dlci, ts0710->dlci[dlci].state, try);
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);
2017 if ((ts0710->dlci[0].state == CONNECTED)
2018 || (ts0710->dlci[0].state == FLOW_STOPPED)) {
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;
2025 } else if (signal_pending(current)) {
2026 printk(KERN_ERR "MUX: id[%d] DLCI:%d Send SABM got signal!\n", self->mux_id, dlci);
2032 if (ts0710->dlci[0].state == CONNECTING) {
2033 ts0710->dlci[0].state = DISCONNECTED;
2036 wake_up_all(&ts0710->dlci[0].open_wait);
2038 } else { /* other channel */
2039 if ((ts0710->dlci[0].state != CONNECTED)
2040 && (ts0710->dlci[0].state != FLOW_STOPPED)) {
2042 } else if ((ts0710->dlci[dlci].state == CONNECTED)
2043 || (ts0710->dlci[dlci].state == FLOW_STOPPED)) {
2045 } else if ((ts0710->dlci[dlci].state == NEGOTIATING)
2046 || (ts0710->dlci[dlci].state == CONNECTING)) {
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);
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);
2061 if ((ts0710->dlci[dlci].state == CONNECTED)
2062 || (ts0710->dlci[dlci].state == FLOW_STOPPED)) {
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);
2069 } else if (ts0710->dlci[dlci].state == DISCONNECTED) {
2070 printk(KERN_ERR "MUX: id[%d] Error DLCI[%d] DISCONNECTED\n", self->mux_id, dlci);
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);
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);
2083 if ((ts0710->dlci[dlci].state == NEGOTIATING)
2084 || (ts0710->dlci[dlci].state == CONNECTING)) {
2085 ts0710->dlci[dlci].state = DISCONNECTED;
2088 } else if ((ts0710->dlci[dlci].state != DISCONNECTED)
2089 && (ts0710->dlci[dlci].state != REJECTED)) {
2092 ts0710->dlci[dlci].state = CONNECTING;
2093 ts0710->dlci[dlci].initiator = 1;
2094 if (ts0710->dlci[dlci].state == CONNECTING) {
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);
2102 TS0710_PRINTK("MUX: id[%d] DLCI:%d after open wait state = %d try = %d", self->mux_id, dlci, ts0710->dlci[dlci].state, try);
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);
2110 if ((ts0710->dlci[dlci].state == CONNECTED)
2111 || (ts0710->dlci[dlci].state ==FLOW_STOPPED)) {
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);
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;
2123 } else if (signal_pending(current)) {
2124 printk(KERN_ERR "MUX: id[%d] DLCI:%d Send SABM got signal!\n", self->mux_id, dlci);
2131 if ((ts0710->dlci[dlci].state == NEGOTIATING)
2132 || (ts0710->dlci[dlci].state == CONNECTING)) {
2133 ts0710->dlci[dlci].state = DISCONNECTED;
2136 wake_up_all(&ts0710->dlci[dlci].open_wait);
2142 static int ts0710_exec_test_cmd(ts0710_con *ts0710)
2144 __u8 *f_buf; /* Frame buffer */
2145 __u8 *d_buf; /* Data buffer */
2146 int retval = -EFAULT;
2149 struct sprd_mux *self = NULL;
2152 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
2156 self = (struct sprd_mux *)ts0710->user_data;
2159 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
2163 MUX_TS0710_DEBUG(self->mux_id, "ts0710_exec_test_cmd\n");
2165 if (ts0710->be_testing) {
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) {
2176 } else if (signal_pending(current)) {
2177 MUX_TS0710_DEBUG(self->mux_id, "Wait for Test_cmd response got signal!\n");
2179 } else if ((jiffies - t) >= 3 * TS0710MUX_TIME_OUT) {
2180 MUX_TS0710_DEBUG(self->mux_id, "Wait for Test_cmd response timeout!\n");
2184 ts0710->be_testing = 1; /* Set the flag */
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)) {
2196 ts0710->be_testing = 0; /* Clear the flag */
2197 ts0710->test_errs = TEST_PATTERN_SIZE;
2198 wake_up_interruptible(&ts0710->test_wait);
2202 for (j = 0; j < TEST_PATTERN_SIZE; j++) {
2203 d_buf[j] = j & 0xFF;
2207 ts0710_test_msg(ts0710, d_buf, TEST_PATTERN_SIZE, MCC_CMD,
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) {
2217 } else if (signal_pending(current)) {
2218 MUX_TS0710_DEBUG(self->mux_id, "Send Test_cmd got signal!\n");
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;
2226 ts0710->be_testing = 0; /* Clear the flag */
2227 wake_up_interruptible(&ts0710->test_wait);
2229 /* Release buffer */
2241 static void mux_sched_send(struct sprd_mux *self)
2244 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
2248 complete(&self->send_completion);
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
2256 int findInBuf(unsigned char *buf, int len, char *needle)
2259 int needleMatchedPos = 0;
2261 if (needle[0] == '\0') {
2265 for (i = 0; i < len; i++) {
2266 if (needle[needleMatchedPos] == buf[i]) {
2268 if (needle[needleMatchedPos] == '\0') {
2269 /* Entire needle was found */
2273 needleMatchedPos = 0;
2280 /****************************
2281 * TTY driver routines
2282 *****************************/
2283 void ts0710_mux_close(int mux_id, int line)
2288 ts0710_con *ts0710 = NULL;
2289 struct sprd_mux *self = NULL;
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);
2296 self = sprd_mux_mgr[mux_id].handle;
2299 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] self is NULL\n", __FUNCTION__, mux_id, line);
2303 ts0710 = self ->connection;
2305 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] ts0710 is NULL\n", __FUNCTION__, mux_id, line);
2309 if (self->open_count[line] > 0) {
2310 self->open_count[line]--;
2313 // The close here and the open in mux_recover_thread may conflict, so wait
2314 if (self->mux_status == MUX_STATE_RECOVERING) {
2317 printk(KERN_INFO "MUX: mux[%d] line[%d] pid[%d] wait close \n", mux_id, line, current->pid);
2319 rval = wait_event_interruptible_timeout(self->modem_ready, self->mux_status == MUX_STATE_READY, TS0710MUX_TIME_OUT);
2322 printk(KERN_WARNING "MUX: %s mux[%d] line[%d] pid[%d] close wait interrupted!\n", __FUNCTION__, mux_id, line, current->pid);
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);
2330 printk(KERN_INFO "MUX: mux[%d] line[%d] pid[%d] closed!\n", mux_id, line, current->pid);
2332 dlci = line2dlci[line];
2333 cmdline = dlci2line[dlci].cmdline;
2334 dataline = dlci2line[dlci].dataline;
2336 if ((self->open_count[cmdline] == 0) && (self->open_count[dataline] == 0)) {
2337 //close current channel first
2338 ts0710_close_channel(ts0710, dlci);
2341 if (self->open_count[line] == 0) {
2342 if ((self->mux_send_info_flags[line])
2343 && (self->mux_send_info[line])
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);
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);
2362 int ts0710_mux_read(int mux_id, int line, const unsigned char *buf, int count, int timeout)
2365 mux_recv_struct *recv_info;
2366 struct sprd_mux *self = NULL;
2367 ts0710_con *ts0710 = NULL;
2369 mux_recv_packet *recv_packet;
2370 unsigned char *buf_pos;
2373 MUX_TS0710_DEBUG(mux_id, "line[%d] pid[%d] count = %d, timeout = %d\n", line, current->pid, count, timeout);
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);
2384 self = sprd_mux_mgr[mux_id].handle;
2387 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] self is NULL\n", __FUNCTION__, mux_id, line);
2391 ts0710 = self ->connection;
2393 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] ts0710 is NULL\n", __FUNCTION__, mux_id, line);
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);
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);
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);
2409 recv_info = self->mux_recv_info[line];
2411 TS0710_PRINTK("MUX Error: mux_write: mux_send_info[%d] == 0\n", line);
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);
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);
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);
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);
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);
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);
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);
2451 mutex_lock(&recv_info->recv_data_lock);
2453 buf_pos = (unsigned char *)buf;
2455 MUX_TS0710_DEBUG(mux_id, "line[%d] pid[%d] length = %d total = %d\n", line, current->pid, recv_info->length, recv_info->total);
2457 //copy data of recv_info before one of the packet
2458 if (recv_info->length != 0) {
2460 cp_cnt = min(count, recv_info->length);
2462 if ((uint32_t)buf > TASK_SIZE) {
2463 memcpy(buf_pos, recv_info->data + recv_info->pos, cp_cnt);
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);
2474 recv_info->length -= cp_cnt;
2475 recv_info->total -= cp_cnt;
2477 self->check_read_sum[line] -= cp_cnt;
2479 if (recv_info->length == 0) {
2482 recv_info->pos += cp_cnt;
2486 while(count > 0 && recv_info->total != 0) {
2487 if ((recv_packet = recv_info->mux_packet)) {
2488 cp_cnt = min(count, recv_packet->length);
2490 if ((uint32_t)buf > TASK_SIZE) {
2491 memcpy(buf_pos, recv_packet->data + recv_packet->pos, cp_cnt);
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);
2503 recv_packet->length -= cp_cnt;
2504 recv_info->total -= cp_cnt;
2505 self->check_read_sum[line] -= cp_cnt;
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);
2512 recv_packet->pos += cp_cnt;
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);
2521 mutex_unlock(&recv_info->recv_data_lock);
2522 mutex_unlock(&recv_info->recv_lock);
2524 MUX_TS0710_DEBUG(mux_id, "line[%d] pid[%d] read = %d\n", line, current->pid, buf_pos - buf);
2526 return buf_pos - buf;
2531 int ts0710_mux_poll_wait(int mux_id, int line, struct file *filp, poll_table *wait)
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;
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);
2545 self = sprd_mux_mgr[mux_id].handle;
2547 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] self is NULL\n", __FUNCTION__, mux_id, line);
2551 ts0710 = self ->connection;
2553 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] ts0710 is NULL\n", __FUNCTION__, mux_id, line);
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);
2563 send_info = self->mux_send_info[line];
2564 recv_info = self->mux_recv_info[line];
2566 poll_wait(filp, &send_info->tx_wait, wait);
2567 poll_wait(filp, &recv_info->rx_wait, wait);
2569 if (recv_info->total != 0 && self->mux_status == MUX_STATE_READY) {
2570 mask |= POLLIN | POLLRDNORM;
2573 if (mux_line_state(mux_id, line) == 0 && self->mux_status == MUX_STATE_READY) {
2574 mask |= POLLOUT | POLLWRNORM;
2581 int ts0710_mux_write(int mux_id, int line, const unsigned char *buf, int count, int timeout)
2584 mux_send_struct *send_info;
2587 struct sprd_mux *self = NULL;
2588 ts0710_con *ts0710 = NULL;
2592 MUX_TS0710_DEBUG(mux_id, "line[%d] pid[%d] count = %d, timeout = %d\n", line, current->pid, count, timeout);
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);
2603 self = sprd_mux_mgr[mux_id].handle;
2606 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] self is NULL\n", __FUNCTION__, mux_id, line);
2610 ts0710 = self ->connection;
2612 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] ts0710 is NULL\n", __FUNCTION__, mux_id, line);
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);
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);
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);
2628 send_info = self->mux_send_info[line];
2630 TS0710_PRINTK("MUX Error: mux_write: mux_send_info[%d] == 0\n", line);
2634 c = min(count, (ts0710->dlci[dlci].mtu - 1));
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);
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);
2652 if (self->mux_status != MUX_STATE_READY)
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);
2658 } else if (timeout < 0){
2659 mutex_lock(&send_info->send_lock);
2661 MUX_TS0710_DEBUG(mux_id, "line[%d] pid[%d] wait write\n", line, current->pid);
2663 rval = wait_event_interruptible(send_info->tx_wait, mux_line_state(mux_id, line) == 0 && self->mux_status == MUX_STATE_READY);
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);
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);
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);
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);
2683 ring_index = send_info->write_index % ringbuf_num[mux_id][line];
2685 d_buf = send_info->buf + (ring_index * TS0710MUX_SEND_BUF_SIZE) + TS0710MUX_SEND_BUF_OFFSET;
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]);
2689 if ((uint32_t)buf > TASK_SIZE) {
2690 memcpy(&d_buf[0], buf, c);
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);
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);
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);
2707 send_info->frame[ring_index] = d_buf;
2709 queue_uih(send_info, ring_index, c, ts0710, dlci);
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);
2715 send_info->write_index++;
2717 mutex_unlock(&send_info->send_lock);
2719 mux_sched_send(self);
2721 // printk(KERN_ERR "MUX: %s mux[%d] line[%d] pid[%d] write = %d\n", __FUNCTION__, mux_id, line, current->pid, c);
2723 MUX_TS0710_DEBUG(mux_id, "line[%d] pid[%d] wait write\n", line, current->pid);
2727 printk(KERN_ERR "MUX: %s mux[%d] line[%d] pid[%d] not connected\n", __FUNCTION__, mux_id, line, current->pid);
2728 return -EDISCONNECTED;
2732 int ts0710_mux_mux_ioctl(int mux_id, int line, unsigned int cmd, unsigned long arg)
2735 struct sprd_mux *self = NULL;
2736 ts0710_con *ts0710 = NULL;
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);
2745 self = sprd_mux_mgr[mux_id].handle;
2748 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] self is NULL\n", __FUNCTION__, mux_id, line);
2752 ts0710 = self ->connection;
2754 printk(KERN_ERR "MUX: Error %s mux[%d] line[%d] ts0710 is NULL\n", __FUNCTION__, mux_id, line);
2758 dlci = line2dlci[line];
2760 case TS0710MUX_IO_MSC_HANGUP:
2761 if (ts0710_msc_msg(ts0710, EA | RTR | DV, MCC_CMD, dlci) < 0) {
2767 case TS0710MUX_IO_TEST_CMD:
2768 return ts0710_exec_test_cmd(ts0710);
2773 return -ENOIOCTLCMD;
2776 int ts0710_mux_open(int mux_id, int line)
2782 mux_send_struct *send_info;
2783 mux_recv_struct *recv_info;
2784 struct sprd_mux *self = NULL;
2785 ts0710_con *ts0710 = NULL;
2789 if ((line < 0) || (line >= NR_MUXS)) {
2790 printk(KERN_ERR "MUX: Error %s line[%d] is wrong\n", __FUNCTION__, line);
2794 self = sprd_mux_mgr[mux_id].handle;
2796 mutex_lock(&self->open_mutex[line]);
2798 ts0710 = self->connection;
2801 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
2805 self->open_count[line]++;
2806 dlci = line2dlci[line];
2808 printk(KERN_INFO "MUX: %s id = %d, dlci = %d, pid = %d\n", __FUNCTION__, self->mux_id, dlci, current->pid);
2810 retval = wait_event_interruptible(self->modem_ready, self->mux_status == MUX_STATE_READY);
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]);
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");
2831 self->cmux_mode = 1;
2832 wake_up(&self->handshake_ready);
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]);
2844 mutex_unlock(&self->handshake_mutex);
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]);
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);
2859 self->open_count[line]--;
2860 mutex_unlock(&self->open_mutex[line]);
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);
2870 self->mux_send_info[line] = send_info;
2871 self->mux_send_info_flags[line] = 1;
2873 MUX_TS0710_DEBUG(self->mux_id, "Allocate mux_send_info for /dev/mux%d\n", line);
2876 if (self->mux_recv_info_flags[line] == 0) {
2877 recv_info = (mux_recv_struct *) kmalloc(sizeof(mux_recv_struct), GFP_KERNEL);
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;
2883 MUX_TS0710_DEBUG(self->mux_id, "Free mux_send_info for /dev/mux%d\n", line);
2886 self->open_count[line]--;
2887 mutex_unlock(&self->open_mutex[line]);
2890 recv_info->length = 0;
2891 recv_info->total = 0;
2892 recv_info->mux_packet = 0;
2894 mutex_init(&recv_info->recv_lock);
2895 mutex_init(&recv_info->recv_data_lock);
2896 init_waitqueue_head(&recv_info->rx_wait);
2898 self->mux_recv_info[line] = recv_info;
2899 self->mux_recv_info_flags[line] = 1;
2901 MUX_TS0710_DEBUG(self->mux_id, "Allocate mux_recv_info for /dev/mux%d\n", line);
2904 /* Now establish DLCI connection */
2905 cmdline = dlci2line[dlci].cmdline;
2906 dataline = dlci2line[dlci].dataline;
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]);
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);
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;
2919 MUX_TS0710_DEBUG(self->mux_id, "Free mux_send_info for /dev/mux%d\n", line);
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);
2926 self->open_count[line]--;
2927 mutex_unlock(&self->open_mutex[line]);
2932 mutex_unlock(&self->open_mutex[line]);
2936 printk(KERN_INFO "MUX: id = %d, dlci = %d, retval = %d\n", self->mux_id, dlci, retval);
2941 static inline int rt_policy(int policy)
2943 if (unlikely(policy == SCHED_FIFO) || unlikely(policy == SCHED_RR))
2948 static inline int task_has_rt_policy(struct task_struct *p)
2950 return rt_policy(p->policy);
2953 /*For BP UART problem Begin*/
2955 static int send_ack(ts0710_con * ts0710, __u8 seq_num, __u8 bp_seq1,
2958 static int send_ack(ts0710_con * ts0710, __u8 seq_num)
2964 static int mux_set_thread_pro(int pro)
2967 struct sched_param s;
2969 /* just for this write, set us real-time */
2970 if (!task_has_rt_policy(current)) {
2971 struct cred *new = prepare_creds();
2974 cap_raise(new->cap_effective, CAP_SYS_NICE);
2976 s.sched_priority = MAX_RT_PRIO - pro;
2977 ret = sched_setscheduler(current, SCHED_RR, &s);
2979 printk(KERN_WARNING "MUX: set priority failed!\n");
2984 /*For BP UART problem End*/
2986 static void receive_worker(struct sprd_mux *self, int start)
2989 unsigned char *search, *to, *from;
2990 short_frame *short_pkt;
2991 long_frame *long_pkt;
2992 /*For BP UART problem Begin */
2994 __u8 *uih_data_start;
2996 /*For BP UART problem End */
2999 if (!self || !self->io_hal || !self->io_hal->io_read) {
3000 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
3005 memset(self->tbuf, 0, TS0710MUX_MAX_BUF_SIZE);
3006 self->tbuf_ptr = self->tbuf;
3007 self->start_flag = 0;
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);
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) {
3021 self->tbuf_ptr += count;
3023 if ((self->start_flag != 0) && (self->framelen != -1)) {
3024 if ((self->tbuf_ptr - self->start_flag) < self->framelen) {
3029 search = &self->tbuf[0];
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) {
3036 self->start_flag = search;
3041 TS0710_PRINTK(">S %02x %c\n", *search, *search);
3047 if (self->start_flag == 0) {
3048 self->tbuf_ptr = &self->tbuf[0];
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 */
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;
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 */
3085 /*For BP UART problem Begin */
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;
3095 crc_error = crc_check((__u8*) (self->start_flag + SLIDE_BP_SEQ_OFFSET), LONG_CRC_CHECK + 1, *(uih_data_start + uih_len));
3097 uih_len = short_pkt->h.length.len;
3098 uih_data_start = short_pkt->data;
3100 crc_error = crc_check((__u8*) (self->start_flag + SLIDE_BP_SEQ_OFFSET), SHORT_CRC_CHECK + 1, *(uih_data_start + uih_len));
3104 if (1) /*expect_seq == *(start_flag + SLIDE_BP_SEQ_OFFSET)*/
3106 self->expect_seq = *(self->start_flag + SLIDE_BP_SEQ_OFFSET);
3108 if (self->expect_seq >= 4){
3109 self->expect_seq = 0;
3112 send_ack(self->connection, self->expect_seq, *(self->start_flag + FIRST_BP_SEQ_OFFSET), *(self->start_flag + SECOND_BP_SEQ_OFFSET));
3114 send_ack(self->connection, self->expect_seq);
3117 ts0710_recv_data(self->connection, self->start_flag + ADDRESS_FIELD_OFFSET, self->framelen - 2 - SEQ_FIELD_SIZE);
3121 if (*(self->start_flag + SLIDE_BP_SEQ_OFFSET) != 0x9F) {
3124 TS0710_PRINTK("MUX sequence number %d is not expected %d, discard data!\n", *(self->start_flag + SLIDE_BP_SEQ_OFFSET), self->expect_seq);
3127 send_ack(self->connection, self->expect_seq, *(self->start_flag + FIRST_BP_SEQ_OFFSET), *(self->start_flag + SECOND_BP_SEQ_OFFSET));
3129 send_ack(self->connection, self->expect_seq);
3134 *(uih_data_start + uih_len) = 0;
3135 TS0710_PRINTK("MUX bp log: %s\n", uih_data_start);
3140 } else { /* crc_error */
3141 search = self->start_flag + 1;
3142 self->start_flag = 0;
3143 self->framelen = -1;
3145 } /*End if(!crc_error) */
3147 search = self->start_flag + self->framelen;
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;
3155 self->start_flag = 0;
3156 self->framelen = -1;
3160 if (self->start_flag != &self->tbuf[0]) {
3163 from = self->start_flag;
3164 count = self->tbuf_ptr - self->start_flag;
3169 self->tbuf_ptr -= (self->start_flag - self->tbuf);
3170 self->start_flag = self->tbuf;
3174 } /* End Frame Start Flag found */
3175 } /* End while(1) */
3178 static int mux_receive_thread(void *data)
3181 struct sprd_mux *self = data;
3184 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
3188 printk(KERN_ERR "MUX: id = %d %s entered\n", self->mux_id, __FUNCTION__);
3190 mux_set_thread_pro(95);
3191 while (!kthread_should_stop()) {
3192 if (self->mux_exiting == 1) {
3193 self->mux_exiting = 2;
3197 wait_event(self->handshake_ready, self->cmux_mode == 1);
3199 receive_worker(self, start);
3205 static int mux_send_thread(void *private_)
3209 mux_send_struct *send_info;
3211 struct sprd_mux *self;
3215 self = (struct sprd_mux *)(private_);
3218 printk(KERN_ERR "MUX: Error %s Self is NULL\n", __FUNCTION__);
3222 printk(KERN_ERR "MUX: id = %d %s entered\n", self->mux_id, __FUNCTION__);
3224 ts0710 = self->connection;
3226 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
3230 if (ts0710->dlci[0].state == FLOW_STOPPED) {
3231 MUX_TS0710_DEBUG(self->mux_id, "Flow stopped on all channels\n");
3235 mux_set_thread_pro(80);
3237 while (!kthread_should_stop()) {
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);
3243 if (!(self->mux_send_info_flags[j])) {
3247 send_info = self->mux_send_info[j];
3252 if (send_info->write_index == send_info->read_index) {
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);
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);
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]);
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);
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]);
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);
3293 wake_up_interruptible(&send_info->tx_wait);
3294 } /* End for() loop */
3301 ssize_t mux_proc_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
3303 return seq_read(file, buf, size, ppos);
3306 static int mux_proc_show(struct seq_file *seq, void *v)
3308 char mux_buf[MUX_MODE_MAX_LEN + 1];
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);
3316 static int mux_proc_open(struct inode *inode, struct file *file)
3318 return single_open(file, mux_proc_show, inode->i_private);
3321 static ssize_t mux_proc_write(struct file *file, const char __user *buf, size_t len, loff_t *ppos)
3323 char mux_buf[len + 1];
3326 memset(mux_buf, 0, len + 1);
3328 if (copy_from_user(mux_buf, buf, len)) {
3329 printk(KERN_ERR "MUX: Error %s failed to copy from user!\n", __FUNCTION__);
3334 val = simple_strtoul(mux_buf, NULL, 10);
3341 static int mux_create_proc(void)
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,
3353 mux_entry = proc_create("mux_mode", 0666, NULL, &mux_fops);
3355 printk(KERN_ERR "MUX: Error Can not create mux proc entry\n");
3362 static void mux_set_ringbuf_num(void)
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;
3373 ringbuf_num[mux_id][line] = 1;
3379 static int mux_line_state(SPRDMUX_ID_E mux_id, int line)
3381 struct sprd_mux *self = NULL;
3382 mux_send_struct *send_info;
3384 self = sprd_mux_mgr[mux_id].handle;
3386 send_info = self->mux_send_info[line];
3389 printk(KERN_ERR "MUX Error: %s: mux_send_info[%d][%d] == 0\n", __FUNCTION__, mux_id, line);
3393 if (send_info->write_index - send_info->read_index >= ringbuf_num[mux_id][line]) {
3394 /* No idle ring buffer */
3401 int sprdmux_line_busy(SPRDMUX_ID_E mux_id, int line)
3403 return mux_line_state(mux_id, line);
3406 void sprdmux_set_line_notify(SPRDMUX_ID_E mux_id, int line, __u8 notify)
3409 struct sprd_mux *self = NULL;
3410 mux_send_struct *send_info;
3412 self = sprd_mux_mgr[mux_id].handle;
3414 send_info = self->mux_send_info[line];
3417 printk(KERN_ERR "MUX Error: %s: mux_send_info[%d][%d] == 0\n", __FUNCTION__, mux_id, line);
3421 send_info->need_notify = notify;
3424 static mux_send_struct * mux_alloc_send_info(SPRDMUX_ID_E mux_id, int line)
3426 mux_send_struct *send_info_ptr = NULL;
3428 send_info_ptr = (mux_send_struct *) kzalloc(sizeof(mux_send_struct), GFP_KERNEL);
3429 if (!send_info_ptr) {
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);
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);
3446 send_info_ptr->frame = (__u8 **)kzalloc(sizeof(__u8 *) * ringbuf_num[mux_id][line], GFP_KERNEL);
3448 if (!send_info_ptr->frame) {
3449 kfree(send_info_ptr->length);
3450 vfree(send_info_ptr->buf);
3451 kfree(send_info_ptr);
3455 return send_info_ptr;
3458 static void mux_free_send_info(mux_send_struct * send_info)
3464 if (send_info->frame) {
3465 kfree(send_info->frame);
3466 send_info->frame = NULL;
3469 if (send_info->length) {
3470 kfree(send_info->length);
3471 send_info->length = NULL;
3474 if (send_info->buf) {
3475 vfree(send_info->buf);
3476 send_info->buf = NULL;
3484 static void mux_remove_proc(void)
3486 remove_proc_entry("mux_mode", NULL); /* remove /proc/mux_mode */
3489 int ts0710_mux_init(void)
3491 create_crctable(crctable);
3493 // mux_mgr_init(sprd_mux_mgr);
3495 if (mux_create_proc()) {
3496 printk(KERN_ERR "MUX: Error %s create mux proc interface failed!\n", __FUNCTION__);
3499 mux_set_ringbuf_num();
3503 void ts0710_mux_exit(void)
3506 mux_mgr_init(sprd_mux_mgr);
3509 int ts0710_mux_create(int mux_id)
3511 struct sprd_mux *self = NULL;
3514 if (mux_id < 0 || mux_id >= SPRDMUX_ID_MAX) {
3515 printk(KERN_ERR "MUX: Error %sInvalid Param\n",__FUNCTION__);
3520 self = (struct sprd_mux *)kzalloc(sizeof(struct sprd_mux), GFP_KERNEL);
3523 printk(KERN_ERR "MUX: Error %s no memory for self\n",__FUNCTION__);
3528 self->mux_id = mux_id;
3530 self->connection = (ts0710_con *)kzalloc(sizeof(ts0710_con), GFP_KERNEL);
3532 if (!self->connection) {
3533 printk(KERN_ERR "MUX: Error %s no memory for connection\n",__FUNCTION__);
3538 self->connection->user_data = (void *)self;
3540 ts0710_init(self->connection);
3542 ts0710_init_waitqueue(self->connection);
3544 mutex_init(&self->handshake_mutex);
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;
3553 mutex_init(&self->open_mutex[j]);
3556 self->framelen = -1;
3557 self->expect_seq = 0;
3558 self->mux_status = MUX_STATE_NOT_READY;
3560 init_completion(&self->send_completion);
3561 init_waitqueue_head(&self->handshake_ready);
3562 init_waitqueue_head(&self->modem_ready);
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;
3572 wake_up_process(self->mux_send_kthread);
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;
3581 wake_up_process(self->mux_recv_kthread);
3583 self->io_hal = &sprd_mux_mgr[mux_id].mux;
3584 sprd_mux_mgr[mux_id].handle = self;
3589 kthread_stop(self->mux_send_kthread);
3590 self->mux_send_kthread = NULL;
3592 kfree(self->connection);
3597 printk(KERN_ERR "MUX: Error %s Create Failed \n",__FUNCTION__);
3605 void ts0710_mux_destory(int mux_id)
3608 struct sprd_mux *self = NULL;
3610 if (mux_id < 0 || mux_id >= SPRDMUX_ID_MAX) {
3611 printk(KERN_ERR "MUX: Error %sInvalid Param\n",__FUNCTION__);
3615 self = sprd_mux_mgr[mux_id].handle;
3618 printk(KERN_ERR "MUX: Error %s Invalid Param self = %x\n", __FUNCTION__, (int)self);
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;
3628 if ((self->mux_recv_info_flags[j]) && (self->mux_recv_info[j])) {
3629 free_mux_recv_struct(self->mux_recv_info[j]);
3631 self->mux_recv_info_flags[j] = 0;
3632 self->mux_recv_info[j] = 0;
3634 self->mux_exiting = 1;
3636 ts0710_close_channel(self->connection, 0);
3637 TS0710_SIG2APLOGD();
3638 self->cmux_mode = 0;
3640 if (!self->io_hal || !self->io_hal->io_stop) {
3641 self->io_hal->io_stop(SPRDMUX_READ);
3644 while (self->mux_exiting == 1) {
3648 if(self->mux_recv_kthread) {
3649 kthread_stop(self->mux_recv_kthread);
3650 self->mux_recv_kthread = NULL;
3653 if(self->mux_send_kthread) {
3654 kthread_stop(self->mux_send_kthread);
3655 self->mux_send_kthread = NULL;
3658 if (self->connection) {
3659 kfree(self->connection);
3662 if (self->mux_recover_kthread) {
3663 kthread_stop(self->mux_recover_kthread);
3664 self->mux_recover_kthread = NULL;
3669 static void mux_print_mux_mgr(void)
3673 printk(KERN_INFO "No MUX_ID Name Handle\n");
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);
3680 static void mux_mgr_init(mux_info *mux_mgr)
3683 mux_print_mux_mgr();
3686 for (j = 0; j < SPRDMUX_MAX_NUM; j++) {
3687 mux_mgr[j].handle = NULL;
3692 int sprdmux_register(struct sprdmux *mux)
3694 if (!mux || mux->id < 0 || mux->id >= SPRDMUX_ID_MAX ) {
3695 printk(KERN_ERR "MUX: %s Invalid Param\n", __FUNCTION__);
3699 memcpy(&sprd_mux_mgr[mux->id].mux, mux, sizeof(struct sprdmux));
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);
3703 ts0710_mux_create(mux->id);
3708 void sprdmux_unregister(SPRDMUX_ID_E mux_id)
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);
3715 memset(&sprd_mux_mgr[mux_id].mux, 0, sizeof(struct sprdmux));
3716 ts0710_mux_destory(mux_id);
3719 int sprdmux_open(SPRDMUX_ID_E mux_id, int index)
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);
3728 rval = ts0710_mux_status(mux_id);
3731 printk(KERN_ERR "MUX: Error %s [%d][%d] mux_status is Not OK\n", __FUNCTION__, mux_id, index);
3735 return ts0710_mux_open(mux_id, index);
3738 void sprdmux_close(SPRDMUX_ID_E mux_id, int index)
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);
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);
3750 ts0710_mux_close(mux_id, index);
3753 int sprdmux_write(SPRDMUX_ID_E mux_id, int index, const unsigned char *buf, int count)
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);
3762 rval = ts0710_mux_status(mux_id);
3765 printk(KERN_ERR "MUX: Error %s [%d][%d] mux_status is Not OK\n", __FUNCTION__, mux_id, index);
3769 return ts0710_mux_write(mux_id, index, buf, count, 0);
3772 int sprdmux_register_notify_callback(SPRDMUX_ID_E mux_id, struct sprdmux_notify *notify)
3774 struct sprd_mux *self = NULL;
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__);
3781 self = sprd_mux_mgr[mux_id].handle;
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;
3792 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
3796 static void mux_display_recv_info(const char * tag, int mux_id, int line)
3798 struct sprd_mux *self = NULL;
3799 mux_recv_struct *recv_info;
3801 mux_recv_packet *recv_packet;
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);
3808 if ((line < 0) || (line >= NR_MUXS)) {
3809 printk(KERN_ERR "MUX: Error %s %sline[%d] is wrong\n", __FUNCTION__, tag, line);
3814 self = sprd_mux_mgr[mux_id].handle;
3817 printk(KERN_ERR "MUX[%d]: Error %s %s self is NULL\n", mux_id, __FUNCTION__, tag);
3818 mux_print_mux_mgr();
3822 recv_info = self->mux_recv_info[line];
3824 if (recv_info == NULL){
3825 printk(KERN_ERR "MUX: Error %s %s mux_recv_info is NULL\n", __FUNCTION__, tag);
3829 sum += recv_info->length;
3831 while((recv_packet = recv_info->mux_packet) != NULL) {
3832 sum += recv_packet->length;
3833 recv_packet = recv_packet->next;
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);
3846 int ts0710_mux_status(int mux_id)
3848 if (mux_id >= SPRDMUX_ID_MAX || mux_id < 0) {
3849 printk(KERN_ERR "MUX: Error %s [%d] Invalid Param\n", __FUNCTION__, mux_id);
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) {
3859 printk(KERN_ERR "MUX: Error %s [%d] status is Not OK\n", __FUNCTION__, mux_id);
3864 static int mux_handshake(struct sprd_mux *self)
3867 char *buff = buffer;
3870 MUX_TS0710_DEBUG(self->mux_id, "cmux_mode = %d\n", self->cmux_mode);
3872 if (self->cmux_mode == 1) {
3873 printk(KERN_ERR "MUX: %s mux_mode is incorrect!\n", __FUNCTION__);
3877 memset(buffer, 0, 256);
3878 printk(KERN_INFO "\n cmux say hello >, id %d \n", self->mux_id);
3880 if (mux_mode == 1) {
3881 count = self->io_hal->io_write("AT+SMMSWAP=0\r", strlen("AT+SMMSWAP=0\r"));
3883 count = self->io_hal->io_write("AT\r", strlen("AT\r"));
3887 printk(KERN_INFO "\n MUX: id = %d,cmux write stoped for crash\n", self->mux_id);
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);
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);
3901 if (findInBuf(buffer, 256, "OK")) {
3903 } else if (findInBuf(buffer, 256, "ERROR")) {
3904 printk(KERN_INFO "\n MUX: id = %d,wrong modem state !!!!\n", self->mux_id);
3907 } else if (count == 0){
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);
3916 if (mux_mode == 1) {
3917 count = self->io_hal->io_write("AT+SMMSWAP=0\r", strlen("AT+SMMSWAP=0\r"));
3919 count = self->io_hal->io_write("AT\r", strlen("AT\r"));
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);
3928 printk(KERN_WARNING "\n MUX: id = %d,wrong modem state !!!!\n", self->mux_id);
3933 count = self->io_hal->io_write("at+cmux=0\r", strlen("at+cmux=0\r"));
3935 printk(KERN_INFO "\n MUX: id = %d,cmux write stoped\n", self->mux_id);
3939 count = self->io_hal->io_read(buffer, sizeof(buffer));
3941 printk(KERN_INFO "\n MUX: id = %d,cmux read stoped\n", self->mux_id);
3945 printk(KERN_INFO "MUX: id = %d, handshake OK\n", self->mux_id);
3950 void mux_ipc_enable(__u8 is_enable)
3953 struct sprd_mux *self;
3955 printk(KERN_INFO "MUX: %s entered enable = %d\n", __FUNCTION__, is_enable);
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;
3961 MUX_TS0710_DEBUG(self->mux_id, "enable = %d old state = %d\n", is_enable, self->mux_status);
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) {
3970 printk(KERN_ERR "MUX: %s wrong enable state \n", __FUNCTION__);
3973 if (self->mux_status == MUX_STATE_NOT_READY) {
3983 static void mux_wakeup_all_read(struct sprd_mux *self)
3986 mux_recv_struct *recv_info;
3989 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
3993 for (j = 0; j < NR_MUXS; j++) {
3994 if (!(self->mux_recv_info_flags[j])) {
3998 recv_info = self->mux_recv_info[j];
4003 wake_up_interruptible(&recv_info->rx_wait);
4007 static void mux_wakeup_all_write(struct sprd_mux *self)
4010 mux_send_struct *send_info;
4013 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4017 for (j = 0; j < NR_MUXS; j++) {
4018 if (!(self->mux_send_info_flags[j])) {
4022 send_info = self->mux_send_info[j];
4027 wake_up_interruptible(&send_info->tx_wait);
4032 static void mux_wakeup_all_opening(struct sprd_mux *self)
4038 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4042 ts0710 = self->connection;
4045 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
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);
4056 static void mux_wakeup_all_closing(struct sprd_mux *self)
4062 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4066 ts0710 = self->connection;
4069 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
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);
4080 static void mux_wakeup_all_wait(struct sprd_mux *self)
4082 mux_wakeup_all_read(self);
4083 mux_wakeup_all_write(self);
4084 mux_wakeup_all_opening(self);
4085 mux_wakeup_all_closing(self);
4087 if (self && self->connection) {
4088 wake_up_interruptible(&self->connection->test_wait);
4092 static void mux_tidy_buff(struct sprd_mux *self)
4096 mux_send_struct *send_info;
4099 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4103 for (j = 0; j < NR_MUXS; j++) {
4104 if (!(self->mux_send_info_flags[j])) {
4108 send_info = self->mux_send_info[j];
4113 for (k = 0; k < ringbuf_num[self->mux_id][j]; k++) {
4114 send_info->length[k] = 0;
4117 send_info->read_index = 0;
4118 send_info->write_index = 0;
4121 memset(self->tbuf, 0, TS0710MUX_MAX_BUF_SIZE);
4122 self->tbuf_ptr = self->tbuf;
4123 self->start_flag = 0;
4124 self->framelen = -1;
4129 static void mux_recover(struct sprd_mux *self)
4132 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4136 MUX_TS0710_DEBUG(self->mux_id, "entered\n");
4138 self->mux_status = MUX_STATE_RECOVERING;
4140 if (self->mux_recover_kthread) {
4141 kthread_stop(self->mux_recover_kthread);
4143 self->mux_recover_kthread = NULL;
4146 self->mux_recover_kthread = kthread_create(mux_recover_thread, self, "mux_recover");
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));
4153 mux_tidy_buff(self);
4155 wake_up_process(self->mux_recover_kthread);
4158 static int mux_recover_thread(void *data)
4160 struct sprd_mux *self = data;
4163 printk(KERN_ERR "MUX: %s self is NULL\n", __FUNCTION__);
4167 printk(KERN_ERR "MUX: id[%d] %s entered\n", self->mux_id, __FUNCTION__);
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;
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;
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__);
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__);
4197 printk(KERN_ERR "MUX: id[%d] %s recover failed retry\n", self->mux_id, __FUNCTION__);
4203 printk(KERN_ERR "MUX: id[%d] %s out\n", self->mux_id, __FUNCTION__);
4208 static void mux_stop(struct sprd_mux *self)
4211 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4215 MUX_TS0710_DEBUG(self->mux_id, "entered\n");
4217 self->mux_status = MUX_STATE_CRASHED;
4218 self->cmux_mode = 0;
4219 self->io_hal->io_stop(SPRDMUX_ALL);
4221 // mux_wakeup_all_read(self);
4222 // mux_wakeup_all_write(self);
4223 mux_wakeup_all_opening(self);
4224 mux_wakeup_all_closing(self);
4226 if (self->connection) {
4227 wake_up_interruptible(&self->connection->test_wait);
4230 if (self->mux_recover_kthread) {
4231 kthread_stop(self->mux_recover_kthread);
4233 self->mux_recover_kthread = NULL;
4239 static void mux_wakeup_channel(ts0710_con * ts0710)
4244 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
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);
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);
4261 static int mux_restore_channel(ts0710_con * ts0710)
4265 struct sprd_mux *self = NULL;
4268 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
4272 self = (struct sprd_mux *)ts0710->user_data;
4274 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4278 mux_display_connection(ts0710, "before restore");
4280 if (ts0710_ctrl_channel_status(self->connection) != 0) {
4281 printk(KERN_ERR "MUX: Error %s ctrl channel status is Not OK\n", __FUNCTION__);
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__);
4299 mux_display_connection(ts0710, "after restore");
4304 static void mux_display_connection(ts0710_con * ts0710, const char *tag)
4308 struct sprd_mux *self = NULL;
4311 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
4315 self = (struct sprd_mux *)ts0710->user_data;
4317 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
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);
4328 static void mux_init_timer(struct sprd_mux *self)
4331 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4335 init_timer(&self->watch_timer);
4338 static void mux_start_timer(struct sprd_mux *self)
4341 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
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;
4349 add_timer(&self->watch_timer);
4352 static void mux_wathch_check(unsigned long priv)
4354 struct sprd_mux *self = (struct sprd_mux *) priv;
4357 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4361 printk(KERN_ERR "MUX: %s called\n", __FUNCTION__);
4363 if (self->cmux_mode == 0) {
4364 self->io_hal->io_stop(self->mux_id);
4368 static void mux_stop_timer(struct sprd_mux *self)
4371 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
4375 del_timer(&self->watch_timer);
4378 static int ts0710_ctrl_channel_status(ts0710_con * ts0710)
4380 int retval = -ENODEV;
4381 struct sprd_mux *self = NULL;
4384 printk(KERN_ERR "MUX: Error %s ts0710 is NULL\n", __FUNCTION__);
4388 self = (struct sprd_mux *)ts0710->user_data;
4390 printk(KERN_ERR "MUX: Error %s self is NULL\n", __FUNCTION__);
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);
4404 mutex_unlock(&self->handshake_mutex);
4410 static void display_send_info(char * tag, SPRDMUX_ID_E mux_id, int line)
4412 struct sprd_mux *self = NULL;
4413 mux_send_struct *send_info;
4415 self = sprd_mux_mgr[mux_id].handle;
4418 printk(KERN_ERR "MUX: %s, %s mux[%d] line[%d] pid[%d] self NULL\n", tag, __FUNCTION__, mux_id, line, current->pid);
4422 send_info = self->mux_send_info[line];
4425 printk(KERN_ERR "MUX: %s, %s mux[%d] line[%d] pid[%d] send_info NULL\n", tag, __FUNCTION__, mux_id, line, current->pid);
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);
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);
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);
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);
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]);
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);
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);
4474 MODULE_LICENSE("GPL");
4475 MODULE_AUTHOR("Harald Welte <laforge@openezx.org>");
4476 MODULE_DESCRIPTION("GSM TS 07.10 Multiplexer");