1 #include <linux/version.h>
2 #include <linux/module.h>
4 #include <linux/kernel.h>
5 #include <linux/init.h>
6 #include <linux/types.h>
7 #include <linux/fcntl.h>
8 #include <linux/interrupt.h>
9 #include <linux/ptrace.h>
10 #include <linux/poll.h>
12 #include <linux/slab.h>
13 #include <linux/tty.h>
14 #include <linux/errno.h>
15 #include <linux/string.h>
16 #include <linux/signal.h>
17 #include <linux/ioctl.h>
18 #include <linux/skbuff.h>
20 #include <linux/spinlock.h>
22 #include <linux/time.h>
23 #include <linux/delay.h>
24 #include <linux/err.h>
25 #include <linux/kfifo.h>
30 #define N_MTKSTP (15 + 1) /* refer to linux tty.h use N_HCI. */
32 #define HCIUARTSETPROTO _IOW('U', 200, int)
34 #define MAX(a,b) ((a) > (b) ? (a) : (b))
35 #define MIN(a,b) ((a) < (b) ? (a) : (b))
38 #define UART_LOG_LOUD 4
39 #define UART_LOG_DBG 3
40 #define UART_LOG_INFO 2
41 #define UART_LOG_WARN 1
42 #define UART_LOG_ERR 0
44 #define MAX_PACKET_ALLOWED 2000
47 unsigned int gDbgLevel = UART_LOG_INFO;
49 #define UART_DBG_FUNC(fmt, arg...) if(gDbgLevel >= UART_LOG_DBG){ printk(KERN_DEBUG PFX "%s: " fmt, __FUNCTION__ ,##arg);}
50 #define UART_INFO_FUNC(fmt, arg...) if(gDbgLevel >= UART_LOG_INFO){ printk(PFX "%s: " fmt, __FUNCTION__ ,##arg);}
51 #define UART_WARN_FUNC(fmt, arg...) if(gDbgLevel >= UART_LOG_WARN){ printk(PFX "%s: " fmt, __FUNCTION__ ,##arg);}
52 #define UART_ERR_FUNC(fmt, arg...) if(gDbgLevel >= UART_LOG_ERR){ printk(PFX "%s: " fmt, __FUNCTION__ ,##arg);}
53 #define UART_TRC_FUNC(f) if(gDbgLevel >= UART_LOG_DBG){ printk(KERN_DEBUG PFX "<%s> <%d>\n", __FUNCTION__, __LINE__);}
56 #include <linux/kfifo.h>
57 #define LDISC_RX_TASKLET 0
58 #define LDISC_RX_WORK 1
60 #if WMT_UART_RX_MODE_WORK
61 #define LDISC_RX LDISC_RX_WORK
63 #define LDISC_RX LDISC_RX_TASKLET
66 #if (LDISC_RX == LDISC_RX_TASKLET)
67 #define LDISC_RX_FIFO_SIZE (0x20000) /*8192 bytes*/
68 struct kfifo *g_stp_uart_rx_fifo = NULL;
69 spinlock_t g_stp_uart_rx_fifo_spinlock;
70 struct tasklet_struct g_stp_uart_rx_fifo_tasklet;
71 #define RX_BUFFER_LEN 1024
72 unsigned char g_rx_data[RX_BUFFER_LEN];
74 //static DEFINE_RWLOCK(g_stp_uart_rx_handling_lock);
75 #elif (LDISC_RX == LDISC_RX_WORK)
77 #define LDISC_RX_FIFO_SIZE (0x4000) /* 16K bytes shall be enough...... */
78 #define LDISC_RX_BUF_SIZE (2048) /* 2K bytes in one shot is enough */
80 UINT8 *g_stp_uart_rx_buf; /* for stp rx data parsing */
81 struct kfifo *g_stp_uart_rx_fifo = NULL; /* for uart tty data receiving */
82 spinlock_t g_stp_uart_rx_fifo_spinlock; /* fifo spinlock */
83 struct workqueue_struct *g_stp_uart_rx_wq; /* rx work queue (do not use system_wq) */
84 struct work_struct *g_stp_uart_rx_work; /* rx work */
88 struct tty_struct *stp_tty = 0x0;
90 unsigned char tx_buf[MTKSTP_BUFFER_SIZE] = {0x0};
93 //struct semaphore buf_mtx;
95 static INT32 mtk_wcn_uart_tx(const UINT8 *data, const UINT32 size, UINT32 *written_size);
98 static inline int stp_uart_tx_wakeup(struct tty_struct *tty)
102 int written_count = 0;
104 //unsigned long flags;
105 // get data from ring buffer
107 UART_DBG_FUNC("++\n");
108 //// spin_lock_irqsave(&buf_lock, flags);
111 if((i > 1000) && (i % 5)== 0)
113 UART_INFO_FUNC("i=(%d), ****** drop data from uart******\n", i);
118 UART_INFO_FUNC("i=(%d)at stp uart **\n", i);
122 len = (wr_idx >= rd_idx) ? (wr_idx - rd_idx) : (MTKSTP_BUFFER_SIZE - rd_idx);
123 if(len > 0 && len < MAX_PACKET_ALLOWED)
127 * ops->write is called by the kernel to write a series of
128 * characters to the tty device. The characters may come from
129 * user space or kernel space. This routine will return the
130 * number of characters actually accepted for writing.
132 set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
133 written = tty->ops->write(tty, &tx_buf[rd_idx], len);
135 UART_ERR_FUNC("Error(i-%d):[pid(%d)(%s)]tty-ops->write FAIL!len(%d)wr(%d)wr_i(%d)rd_i(%d)\n\r", i, current->pid, current->comm, len, written, wr_idx, rd_idx);
138 written_count = written;
139 //printk("len = %d, written = %d\n", len, written);
140 rd_idx = ((rd_idx + written) % MTKSTP_BUFFER_SIZE);
141 // all data is accepted by UART driver, check again in case roll over
142 len = (wr_idx >= rd_idx) ? (wr_idx - rd_idx) : (MTKSTP_BUFFER_SIZE - rd_idx);
143 if(len > 0 && len < MAX_PACKET_ALLOWED)
145 set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
146 written = tty->ops->write(tty, &tx_buf[rd_idx], len);
149 UART_ERR_FUNC("Error(i-%d):[pid(%d)(%s)]len(%d)wr(%d)wr_i(%d)rd_i(%d)\n\r", i, current->pid, current->comm, len, written, wr_idx, rd_idx);
152 rd_idx = ((rd_idx + written) % MTKSTP_BUFFER_SIZE);
153 written_count += written;
155 else if(len < 0 || len >= MAX_PACKET_ALLOWED)
157 UART_ERR_FUNC("Warnning(i-%d):[pid(%d)(%s)]length verfication(external) warnning,len(%d), wr_idx(%d), rd_idx(%d)!\n\r", i, current->pid, current->comm, len, wr_idx, rd_idx);
163 UART_ERR_FUNC("Warnning(i-%d):[pid(%d)(%s)]length verfication(external) warnning,len(%d), wr_idx(%d), rd_idx(%d)!\n\r", i, current->pid, current->comm, len, wr_idx, rd_idx);
167 //// spin_unlock_irqrestore(&buf_lock, flags);
168 UART_DBG_FUNC("--\n");
169 return written_count;
172 /* ------ LDISC part ------ */
175 * Called when line discipline changed to HCI_UART.
178 * tty pointer to tty info structure
180 * 0 if success, otherwise error code
182 static int stp_uart_tty_open(struct tty_struct *tty)
184 UART_DBG_FUNC("stp_uart_tty_opentty: %p\n", tty);
186 tty->receive_room = 65536;
187 tty->low_latency = 1;
189 /* Flush any pending characters in the driver and line discipline. */
191 /* FIXME: why is this needed. Note don't use ldisc_ref here as the
192 open path is before the ldisc is referencable */
194 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
195 /* definition changed!! */
196 if (tty->ldisc->ops->flush_buffer) {
197 tty->ldisc->ops->flush_buffer(tty);
200 if (tty->ldisc.ops->flush_buffer) {
201 tty->ldisc.ops->flush_buffer(tty);
205 tty_driver_flush_buffer(tty);
207 // init_MUTEX(&buf_mtx);
208 //// spin_lock_init(&buf_lock);
212 mtk_wcn_stp_register_if_tx(STP_UART_IF_TX, mtk_wcn_uart_tx);
217 /* stp_uart_tty_close()
219 * Called when the line discipline is changed to something
220 * else, the tty is closed, or the tty detects a hangup.
222 static void stp_uart_tty_close(struct tty_struct *tty)
224 UART_DBG_FUNC("stp_uart_tty_close(): tty %p\n", tty);
225 mtk_wcn_stp_register_if_tx(STP_UART_IF_TX, NULL);
230 /* stp_uart_tty_wakeup()
232 * Callback for transmit wakeup. Called when low level
233 * device driver can accept more send data.
235 * Arguments: tty pointer to associated tty instance data
238 static void stp_uart_tty_wakeup(struct tty_struct *tty)
240 //printk("%s: start !!\n", __FUNCTION__);
242 //clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
244 //stp_uart_tx_wakeup(tty);
249 /* stp_uart_tty_receive()
251 * Called by tty low level driver when receive data is
254 * Arguments: tty pointer to tty isntance data
255 * data pointer to received data
256 * flags pointer to flags for data
257 * count count of received data in bytes
261 #if (LDISC_RX == LDISC_RX_TASKLET)
263 static int stp_uart_fifo_init(void)
267 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
269 spin_lock_init(&g_stp_uart_rx_fifo_spinlock);
270 g_stp_uart_rx_fifo = kfifo_alloc(LDISC_RX_FIFO_SIZE, GFP_ATOMIC, &g_stp_uart_rx_fifo_spinlock);
271 if (NULL == g_stp_uart_rx_fifo)
273 UART_ERR_FUNC("kfifo_alloc failed (kernel version < 2.6.35)\n");
279 g_stp_uart_rx_fifo = kzalloc(sizeof(struct kfifo), GFP_ATOMIC);
280 if (NULL == g_stp_uart_rx_fifo)
283 UART_ERR_FUNC("kzalloc for g_stp_uart_rx_fifo failed (kernel version > 2.6.35)\n");
285 err = kfifo_alloc(g_stp_uart_rx_fifo, LDISC_RX_FIFO_SIZE, GFP_ATOMIC);
288 UART_ERR_FUNC("kfifo_alloc failed, errno(%d)(kernel version > 2.6.35)\n", err);
289 kfree(g_stp_uart_rx_fifo);
290 g_stp_uart_rx_fifo = NULL;
297 if (NULL != g_stp_uart_rx_fifo)
299 kfifo_reset(g_stp_uart_rx_fifo);
300 UART_ERR_FUNC("stp_uart_fifo_init() success.\n");
305 UART_ERR_FUNC("abnormal case, err = 0 but g_stp_uart_rx_fifo = NULL, set err to %d\n", err);
310 UART_ERR_FUNC("stp_uart_fifo_init() failed.\n");
315 static int stp_uart_fifo_deinit(void)
317 if (NULL != g_stp_uart_rx_fifo)
319 kfifo_free(g_stp_uart_rx_fifo);
320 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
323 kfree(g_stp_uart_rx_fifo);
325 g_stp_uart_rx_fifo = NULL;
330 static void stp_uart_rx_handling(unsigned long func_data){
331 unsigned int how_much_get = 0;
332 unsigned int how_much_to_get = 0;
333 unsigned int flag = 0;
335 // read_lock(&g_stp_uart_rx_handling_lock);
336 how_much_to_get = kfifo_len(g_stp_uart_rx_fifo);
338 if (how_much_to_get >= RX_BUFFER_LEN)
341 UART_INFO_FUNC ("fifolen(%d)\n", how_much_to_get);
345 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
346 how_much_get= kfifo_get(g_stp_uart_rx_fifo, g_rx_data, RX_BUFFER_LEN);
348 how_much_get= kfifo_out(g_stp_uart_rx_fifo, g_rx_data, RX_BUFFER_LEN);
350 //UART_INFO_FUNC ("fifoget(%d)\n", how_much_get);
351 mtk_wcn_stp_parser_data((UINT8 *)g_rx_data, how_much_get);
352 how_much_to_get = kfifo_len(g_stp_uart_rx_fifo);
353 }while(how_much_to_get > 0);
355 // read_unlock(&g_stp_uart_rx_handling_lock);
358 UART_INFO_FUNC ("finish, fifolen(%d)\n", kfifo_len(g_stp_uart_rx_fifo));
362 static void stp_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count)
364 unsigned int fifo_avail_len = LDISC_RX_FIFO_SIZE - kfifo_len(g_stp_uart_rx_fifo);
365 unsigned int how_much_put = 0;
369 do_gettimeofday(&now);
370 printk("[+STP][ ][R] %4d --> sec = %lu, --> usec --> %lu\n",
371 count, now.tv_sec, now.tv_usec);
374 // write_lock(&g_stp_uart_rx_handling_lock);
377 UART_ERR_FUNC("abnormal: buffer count = %d\n", count);
379 /*How much empty seat?*/
380 if(fifo_avail_len > 0){
381 //UART_INFO_FUNC ("fifo left(%d), count(%d)\n", fifo_avail_len, count);
382 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
383 how_much_put = kfifo_put(g_stp_uart_rx_fifo,(unsigned char *) data, count);
385 how_much_put = kfifo_in(g_stp_uart_rx_fifo,(unsigned char *) data, count);
389 tasklet_schedule(&g_stp_uart_rx_fifo_tasklet);
391 UART_ERR_FUNC("stp_uart_tty_receive rxfifo is full!!\n");
397 do_gettimeofday(&now);
398 printk("[-STP][ ][R] %4d --> sec = %lu, --> usec --> %lu\n",
399 count, now.tv_sec, now.tv_usec);
403 // write_unlock(&g_stp_uart_rx_handling_lock);
406 #elif (LDISC_RX ==LDISC_RX_WORK)
407 static int stp_uart_fifo_init(void)
411 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
412 g_stp_uart_rx_buf = vzalloc(LDISC_RX_BUF_SIZE);
413 if (!g_stp_uart_rx_buf) {
414 UART_ERR_FUNC("kfifo_alloc failed (kernel version >= 2.6.37)\n");
419 g_stp_uart_rx_buf = vmalloc(LDISC_RX_BUF_SIZE);
420 if (!g_stp_uart_rx_buf) {
421 UART_ERR_FUNC("kfifo_alloc failed (kernel version < 2.6.37)\n");
425 memset(g_stp_uart_rx_buf, 0, LDISC_RX_BUF_SIZE);
428 UART_INFO_FUNC("g_stp_uart_rx_buf alloc ok(0x%p, %d)\n",
429 g_stp_uart_rx_buf, LDISC_RX_BUF_SIZE);
432 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33))
433 spin_lock_init(&g_stp_uart_rx_fifo_spinlock);
434 g_stp_uart_rx_fifo = kfifo_alloc(LDISC_RX_FIFO_SIZE, GFP_KERNEL, &g_stp_uart_rx_fifo_spinlock);
435 if (NULL == g_stp_uart_rx_fifo) {
436 UART_ERR_FUNC("kfifo_alloc failed (kernel version < 2.6.33)\n");
441 /* allocate struct kfifo first */
442 g_stp_uart_rx_fifo = kzalloc(sizeof(struct kfifo), GFP_KERNEL);
443 if (NULL == g_stp_uart_rx_fifo) {
445 UART_ERR_FUNC("kzalloc struct kfifo failed (kernel version > 2.6.33)\n");
449 /* allocate kfifo data buffer then */
450 err = kfifo_alloc(g_stp_uart_rx_fifo, LDISC_RX_FIFO_SIZE, GFP_KERNEL);
452 UART_ERR_FUNC("kfifo_alloc failed, err(%d)(kernel version > 2.6.33)\n", err);
453 kfree(g_stp_uart_rx_fifo);
454 g_stp_uart_rx_fifo = NULL;
459 UART_INFO_FUNC("g_stp_uart_rx_fifo alloc ok\n");
465 kfifo_reset(g_stp_uart_rx_fifo);
466 UART_DBG_FUNC("g_stp_uart_rx_fifo init success\n");
469 UART_ERR_FUNC("stp_uart_fifo_init() fail(%d)\n", err);
470 if (g_stp_uart_rx_buf) {
471 UART_ERR_FUNC("free g_stp_uart_rx_buf\n");
472 vfree(g_stp_uart_rx_buf);
473 g_stp_uart_rx_buf = NULL;
480 static int stp_uart_fifo_deinit(void)
482 if (g_stp_uart_rx_buf) {
483 vfree(g_stp_uart_rx_buf);
484 g_stp_uart_rx_buf = NULL;
487 if (NULL != g_stp_uart_rx_fifo) {
488 kfifo_free(g_stp_uart_rx_fifo);
489 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33))
492 kfree(g_stp_uart_rx_fifo);
494 g_stp_uart_rx_fifo = NULL;
499 static void stp_uart_fifo_reset (void) {
500 if (NULL != g_stp_uart_rx_fifo) {
501 kfifo_reset(g_stp_uart_rx_fifo);
505 static void stp_uart_rx_worker (struct work_struct *work)
509 if (unlikely(!g_stp_uart_rx_fifo)) {
510 UART_ERR_FUNC("NULL rx fifo!\n");
513 if (unlikely(!g_stp_uart_rx_buf)) {
514 UART_ERR_FUNC("NULL rx buf!\n");
519 /* run until fifo becomes empty */
520 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33))
521 while (kfifo_len(g_stp_uart_rx_fifo)) {
522 read = kfifo_get(g_stp_uart_rx_fifo, g_stp_uart_rx_buf, LDISC_RX_BUF_SIZE);
523 //UART_LOUD_FUNC("kfifo_get(%d)\n", read);
525 mtk_wcn_stp_parser_data((UINT8 *)g_stp_uart_rx_buf, read);
529 while (!kfifo_is_empty(g_stp_uart_rx_fifo)) {
530 read = kfifo_out(g_stp_uart_rx_fifo, g_stp_uart_rx_buf, LDISC_RX_BUF_SIZE);
531 UART_DBG_FUNC("kfifo_out(%d)\n", read);
532 //printk("rx_work:%d\n\r",read);
534 //UART_LOUD_FUNC("->%d\n", read);
535 mtk_wcn_stp_parser_data((UINT8 *)g_stp_uart_rx_buf, read);
536 //UART_LOUD_FUNC("<-\n", read);
544 /* stp_uart_tty_receive()
546 * Called by tty low level driver when receive data is
549 * Arguments: tty pointer to tty isntance data
550 * data pointer to received data
551 * flags pointer to flags for data
552 * count count of received data in bytes
556 static void stp_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count)
558 unsigned int written;
560 //UART_LOUD_FUNC("URX:%d\n", count);
561 if (unlikely(count > 2000)) {
562 UART_WARN_FUNC("abnormal: buffer count = %d\n", count);
565 if (unlikely(!g_stp_uart_rx_fifo || !g_stp_uart_rx_work || !g_stp_uart_rx_wq)) {
566 UART_ERR_FUNC("abnormal g_stp_uart_rx_fifo(0x%p),g_stp_uart_rx_work(0x%p),g_stp_uart_rx_wq(0x%p)\n",
567 g_stp_uart_rx_fifo, g_stp_uart_rx_work, g_stp_uart_rx_wq);
571 /* need to check available buffer size? skip! */
573 /* need to lock fifo? skip for single writer single reader! */
575 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33))
576 written = kfifo_put(g_stp_uart_rx_fifo, (unsigned char *) data, count);
578 written = kfifo_in(g_stp_uart_rx_fifo, (unsigned char *) data, count);
580 //printk("uart_rx:%d,wr:%d\n\r",count,written);
582 queue_work(g_stp_uart_rx_wq, g_stp_uart_rx_work);
584 if (unlikely(written != count)) {
585 UART_ERR_FUNC("c(%d),w(%d) bytes dropped\n", count, written);
593 static void stp_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count)
597 mtk_wcn_stp_debug_gpio_assert(IDX_STP_RX_PROC, DBG_TIE_LOW);
602 UART_ERR_FUNC("stp_uart_tty_receive buffer count = %d\n", count);
609 do_gettimeofday(&now);
611 printk("[+STP][ ][R] %4d --> sec = %d, --> usec --> %d\n",
612 count, now.tv_sec, now.tv_usec);
617 /*There are multi-context to access here? Need to spinlock?*/
618 /*Only one context: flush_to_ldisc in tty_buffer.c*/
619 mtk_wcn_stp_parser_data((UINT8 *)data, (UINT32)count);
622 mtk_wcn_stp_debug_gpio_assert(IDX_STP_RX_PROC, DBG_TIE_HIGH);
631 do_gettimeofday(&now);
633 printk("[-STP][ ][R] %4d --> sec = %d, --> usec --> %d\n",
634 count, now.tv_sec, now.tv_usec);
641 /* stp_uart_tty_ioctl()
643 * Process IOCTL system call for the tty device.
647 * tty pointer to tty instance data
648 * file pointer to open file object for device
649 * cmd IOCTL command code
650 * arg argument for IOCTL call (cmd dependent)
652 * Return Value: Command dependent
654 static int stp_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
655 unsigned int cmd, unsigned long arg)
659 UART_DBG_FUNC("%s =>\n", __FUNCTION__);
662 case HCIUARTSETPROTO:
663 UART_DBG_FUNC("<!!> Set low_latency to TRUE <!!>\n");
664 tty->low_latency = 1;
667 UART_DBG_FUNC("<!!> n_tty_ioctl_helper <!!>\n");
668 err = n_tty_ioctl_helper(tty, file, cmd, arg);
671 UART_DBG_FUNC("%s <=\n", __FUNCTION__);
677 * We don't provide read/write/poll interface for user space.
679 static ssize_t stp_uart_tty_read(struct tty_struct *tty, struct file *file,
680 unsigned char __user *buf, size_t nr)
685 static ssize_t stp_uart_tty_write(struct tty_struct *tty, struct file *file,
686 const unsigned char *data, size_t count)
691 static unsigned int stp_uart_tty_poll(struct tty_struct *tty,
692 struct file *filp, poll_table *wait)
697 INT32 mtk_wcn_uart_tx(const UINT8 *data, const UINT32 size, UINT32 *written_size)
701 //unsigned long flags;
705 if(stp_tty == NULL) return -1;
706 UART_DBG_FUNC("++\n");
709 // put data into ring buffer
715 spin_lock_irqsave is redundant
717 //spin_lock_irqsave(&buf_lock, flags);
719 room = (wr_idx >= rd_idx) ? (MTKSTP_BUFFER_SIZE - (wr_idx - rd_idx) - 1) : (rd_idx - wr_idx - 1);
720 UART_DBG_FUNC("r(%d)s(%d)wr_i(%d)rd_i(%d)\n\r", room, size, wr_idx, rd_idx);
723 Block copy instead of byte copying
726 UART_ERR_FUNC("pid(%d)(%s): data is NULL\n", current->pid, current->comm);
728 UART_DBG_FUNC("--\n");
733 if(unlikely(size > room)){
734 UART_ERR_FUNC("pid(%d)(%s)room is not available, size needed(%d), wr_idx(%d), rd_idx(%d), room left(%d)\n", current->pid, current->comm, size, wr_idx, rd_idx, room);
735 UART_DBG_FUNC("--\n");
741 wr_idx : the position next to write
742 rd_idx : the position next to read
744 len = min(size, MTKSTP_BUFFER_SIZE - (unsigned int)wr_idx);
745 memcpy(&tx_buf[wr_idx], &data[0], len);
746 memcpy(&tx_buf[0], &data[len], size - len);
747 wr_idx = (wr_idx + size) % MTKSTP_BUFFER_SIZE;
748 UART_DBG_FUNC("r(%d)s(%d)wr_i(%d)rd_i(%d)\n\r", room, size, wr_idx, rd_idx);
752 UART_ERR_FUNC("Error(i-%d):[pid(%d)(%s)]len(%d)size(%d)wr_i(%d)rd_i(%d)\n\r", i, current->pid, current->comm, len, size, wr_idx, rd_idx);
759 else if (size < MAX_PACKET_ALLOWED)
761 //only size ~(0, 2000) is allowed
762 (*written_size) = stp_uart_tx_wakeup(stp_tty);
763 if(*written_size < 0)
765 //reset read and write index of tx_buffer, is there any risk?
772 //we filter all packet with size > 2000
773 UART_ERR_FUNC("Warnning(i-%d):[pid(%d)(%s)]len(%d)size(%d)wr_i(%d)rd_i(%d)\n\r", i, current->pid, current->comm, len, size, wr_idx, rd_idx);
781 while((room > 0) && (size > 0))
783 tx_buf[wr_idx] = data[idx];
784 wr_idx = ((wr_idx + 1) % MTKSTP_BUFFER_SIZE);
794 spin_lock_irqsave is redundant
796 //// spin_lock_irqsave(&buf_lock, flags);
798 /*[PatchNeed]To add a tasklet to shedule Uart Tx*/
799 UART_DBG_FUNC("--\n");
803 static int __init mtk_wcn_stp_uart_init(void)
805 static struct tty_ldisc_ops stp_uart_ldisc;
807 int fifo_init_done =0;
809 UART_INFO_FUNC("mtk_wcn_stp_uart_init(): MTK STP UART driver\n");
811 #if (LDISC_RX == LDISC_RX_TASKLET)
812 err = stp_uart_fifo_init();
819 tasklet_init(&g_stp_uart_rx_fifo_tasklet, stp_uart_rx_handling, (unsigned long) 0);
821 #elif (LDISC_RX == LDISC_RX_WORK)
822 err = stp_uart_fifo_init();
824 UART_ERR_FUNC("stp_uart_fifo_init(WORK) error(%d)\n", err);
830 g_stp_uart_rx_work = vmalloc(sizeof(struct work_struct));
831 if (!g_stp_uart_rx_work) {
832 UART_ERR_FUNC("vmalloc work_struct(%d) fail\n", sizeof(struct work_struct));
837 g_stp_uart_rx_wq = create_singlethread_workqueue("mtk_urxd");
838 if (!g_stp_uart_rx_wq) {
839 UART_ERR_FUNC("create_singlethread_workqueue fail\n");
845 INIT_WORK(g_stp_uart_rx_work, stp_uart_rx_worker);
849 /* Register the tty discipline */
850 memset(&stp_uart_ldisc, 0, sizeof (stp_uart_ldisc));
851 stp_uart_ldisc.magic = TTY_LDISC_MAGIC;
852 stp_uart_ldisc.name = "n_mtkstp";
853 stp_uart_ldisc.open = stp_uart_tty_open;
854 stp_uart_ldisc.close = stp_uart_tty_close;
855 stp_uart_ldisc.read = stp_uart_tty_read;
856 stp_uart_ldisc.write = stp_uart_tty_write;
857 stp_uart_ldisc.ioctl = stp_uart_tty_ioctl;
858 stp_uart_ldisc.poll = stp_uart_tty_poll;
859 stp_uart_ldisc.receive_buf = stp_uart_tty_receive;
860 stp_uart_ldisc.write_wakeup = stp_uart_tty_wakeup;
861 stp_uart_ldisc.owner = THIS_MODULE;
863 if ((err = tty_register_ldisc(N_MTKSTP, &stp_uart_ldisc)))
865 UART_ERR_FUNC("MTK STP line discipline registration failed. (%d)\n", err);
870 mtk_wcn_stp_register_if_tx( mtk_wcn_uart_tx);
877 #if (LDISC_RX == LDISC_RX_TASKLET)
879 if (fifo_init_done) {
880 stp_uart_fifo_deinit();
882 #elif (LDISC_RX == LDISC_RX_WORK)
883 if (g_stp_uart_rx_wq) {
884 destroy_workqueue(g_stp_uart_rx_wq);
885 g_stp_uart_rx_wq = NULL;
887 if (g_stp_uart_rx_work) {
888 vfree(g_stp_uart_rx_work);
890 if (fifo_init_done) {
891 stp_uart_fifo_deinit();
894 UART_ERR_FUNC("init fail, return(%d)\n", err);
900 static void __exit mtk_wcn_stp_uart_exit(void)
904 mtk_wcn_stp_register_if_tx(STP_UART_IF_TX, NULL); // unregister if_tx function
906 /* Release tty registration of line discipline */
907 if ((err = tty_unregister_ldisc(N_MTKSTP)))
909 UART_ERR_FUNC("Can't unregister MTK STP line discipline (%d)\n", err);
912 #if (LDISC_RX == LDISC_RX_TASKLET)
913 tasklet_kill(&g_stp_uart_rx_fifo_tasklet);
914 stp_uart_fifo_deinit();
915 #elif (LDISC_RX == LDISC_RX_WORK)
916 if (g_stp_uart_rx_work) {
917 cancel_work_sync(g_stp_uart_rx_work);
919 if (g_stp_uart_rx_wq) {
920 destroy_workqueue(g_stp_uart_rx_wq);
921 g_stp_uart_rx_wq = NULL;
923 if (g_stp_uart_rx_work) {
924 vfree(g_stp_uart_rx_work);
925 g_stp_uart_rx_work = NULL;
927 stp_uart_fifo_deinit();
933 module_init(mtk_wcn_stp_uart_init);
934 module_exit(mtk_wcn_stp_uart_exit);
936 MODULE_LICENSE("GPL");
937 MODULE_AUTHOR("MediaTek Inc WCN_SE_CS3");
938 MODULE_DESCRIPTION("STP-HIF UART Interface");