e8787c57109913a3f6d008b5320ddf750ec367ed
[10.03/openwrt.git] / target / linux / ifxmips / files / drivers / char / ifxmips_mei_core.c
1 /******************************************************************************
2 **
3 ** FILE NAME    : ifxmips_mei_core.c
4 ** PROJECT      : Danube
5 ** MODULES      : MEI
6 **
7 ** DATE         : 1 Jan 2006
8 ** AUTHOR       : TC Chen
9 ** DESCRIPTION  : MEI Driver
10 ** COPYRIGHT    :       Copyright (c) 2006
11 **                      Infineon Technologies AG
12 **                      Am Campeon 1-12, 85579 Neubiberg, Germany
13 **
14 **    This program is free software; you can redistribute it and/or modify
15 **    it under the terms of the GNU General Public License as published by
16 **    the Free Software Foundation; either version 2 of the License, or
17 **    (at your option) any later version.
18 **
19 ** HISTORY
20 ** $Version $Date      $Author     $Comment
21    1.00.01             TC Chen     Fixed cell rate calculation issue
22                                    Fixed pvovider_id of adsl mib swapping issue
23    1.00.02             TC Chen     Added L3 Low Poewr Mode support.   
24    1.00.03             TC Chen     Fixed Clear Eoc transmit issue.
25    1.00.04  31/08/2006 TC Chen     Add ADSL Link/Data Led 
26                                    Add Dual Latency Path
27                                    Add AUTOBOOT_ENABLE_SET ioctl for autoboot 
28                                         mode enable/disable  
29                                    Fix fast path cell rate calculation
30    1.00.05  25/09/2006 TC Chen     Fix ATM QoS fail on interface 0(fast path).
31    1.00.06  02/10/2006 TC Chen     Change ifxmips_ppe_set_cell_rate to 
32                                         ifx_atm_set_cell_rate
33                                    Add ATM Led callback function
34    1.00.07  13/11/2006 TC Chen     Invert ADSL Link LED Signal
35    1.00.08  08/12/2006 TC Chen     Fix loop diagnostic warning message issue
36    1.00.09  20/12/2006 TC Chen     Workaround for USB OC interrupt which is trigegred once DSL reset
37 ******************************************************************************/
38
39 /*
40  * ===========================================================================
41  *                           INCLUDE FILES
42  * ===========================================================================
43  */
44
45 #include <asm/ifxmips/ifxmips_mei_linux.h>
46
47 char IFXMIPS_MEI_VERSION[] = "1.00.09";
48
49 #define IFXMIPS_MEI_CMV_EXTRA   //WINHOST debug
50 #define IFX_ADSL_L3_MODE_SUPPORT        //L3 Low Power Mode Support
51 #define IFX_ADSL_DUAL_LATENCY_SUPPORT
52 #undef IFXMIPS_CLEAR_EOC                //clear eoc support
53
54 // for ARC memory access
55 #define WHILE_DELAY 20000
56 #if defined(IFXMIPS_PORT_RTEMS)
57 #undef IFXMIPS_DMA_DEBUG_MUTEX
58 #else
59 #define IFXMIPS_DMA_DEBUG_MUTEX
60 #endif
61
62 #define IMAGE_SWAP
63 #define BOOT_SWAP
64 #define HEADER_SWAP
65
66 //TODO
67 #undef DFE_LOOPBACK             // testing code //undefined by Henry , start to real link test.
68                     //165203:henryhsu 
69
70 #ifdef DFE_LOOPBACK
71 //#define DFE_MEM_TEST
72 //#define DFE_PING_TEST
73 #define DFE_ATM_LOOPBACK
74 #endif
75
76 #undef DATA_LED_ON_MODE
77 #define DATA_LED_SUPPORT        // support adsl data led
78 //#define DATA_LED_ADSL_FW_HANDLE // adsl data led handle by firmware
79 #define CONFIG_IFXMIPS_MEI_LED  // adsl led support
80
81 //  Block size per BAR
82 #define SDRAM_SEGMENT_SIZE      (64*1024)
83 // Number of Bar registers
84 #define MAX_BAR_REGISTERS       (17)
85
86 #define XDATA_REGISTER          (15)
87
88 #define IFXMIPS_MEI_DEVNAME "mei"
89
90 #ifdef DFE_LOOPBACK
91 #ifndef UINT32
92 #define UINT32 unsigned long
93 #endif
94 #ifdef DFE_PING_TEST
95 #include "dsp_xmem_arb_rand_em.h"
96 #endif
97 #ifdef DFE_MEM_TEST
98 #include "aai_mem_test.h"
99 #endif
100 #ifdef DFE_ATM_LOOPBACK
101 #include "aai_lpbk_dyn_rate.h"
102 #endif
103 #endif
104
105 /************************************************************************
106  *  Function declaration
107  ************************************************************************/
108 static MEI_ERROR meiDMAWrite (u32 destaddr, u32 * databuff, u32 databuffsize);
109 static MEI_ERROR meiDMARead (u32 srcaddr, u32 * databuff, u32 databuffsize);
110 static void meiControlModeSwitch (int mode);
111 static void meiPollForDbgDone (void);
112 static MEI_ERROR _meiDebugLongWordRead (u32 DEC_mode, u32 address,
113                                         u32 * data);
114 static MEI_ERROR _meiDebugLongWordWrite (u32 DEC_mode, u32 address, u32 data);
115 MEI_ERROR meiDebugWrite (u32 destaddr, u32 * databuff, u32 databuffsize);
116 static MEI_ERROR meiDebugRead (u32 srcaddr, u32 * databuff, u32 databuffsize);
117 static MEI_ERROR meiMailboxWrite (u16 * msgsrcbuffer, u16 msgsize);
118 static MEI_ERROR meiDownloadBootCode (void);
119 static MEI_ERROR meiHaltArc (void);
120 static MEI_ERROR meiRunArc (void);
121 static MEI_ERROR meiRunAdslModem (void);
122 static int meiGetPage (u32 Page, u32 data, u32 MaxSize, u32 * Buffer,
123                        u32 * Dest);
124 void makeCMV (u8 opcode, u8 group, u16 address, u16 index, int size,
125               u16 * data, u16 * CMVMSG);
126 MEI_ERROR meiCMV (u16 * request, int reply, u16 * response);
127 static void meiMailboxInterruptsDisable (void);
128 static void meiMailboxInterruptsEnable (void);
129 static int update_bar_register (int nTotalBar);
130 static int free_image_buffer (int type);
131 static int alloc_processor_memory (unsigned long size,
132                                    smmu_mem_info_t * adsl_mem_info);
133 ssize_t mei_write (MEI_file_t * filp, char *buf, size_t size, loff_t * loff);
134 int mei_ioctl (MEI_inode_t * ino, MEI_file_t * fil, unsigned int command,
135                unsigned long lon);
136
137 #ifdef CONFIG_PROC_FS
138 static int proc_read (struct file *file, char *buf, size_t nbytes,
139                       loff_t * ppos);
140 static ssize_t proc_write (struct file *file, const char *buffer,
141                            size_t count, loff_t * ppos);
142 #endif
143
144 #ifdef CONFIG_IFXMIPS_MEI_MIB
145 int mei_mib_ioctl (MEI_inode_t * ino, MEI_file_t * fil, unsigned int command,
146                    unsigned long lon);
147 int mei_mib_adsl_link_up (void);
148 int mei_mib_adsl_link_down (void);
149 int ifxmips_mei_mib_init (void);
150 int ifxmips_mei_mib_cleanup (void);
151 #endif
152 #if defined(CONFIG_IFXMIPS_MEI_LED) && defined(DATA_LED_SUPPORT)
153 static int ifxmips_mei_led_init (void);
154 static int ifxmips_mei_led_cleanup (void);
155 static int adsl_led_flash_task (void);
156 #endif
157 // for clearEoC 
158 #ifdef IFXMIPS_CLEAR_EOC
159 extern void ifx_push_eoc (struct sk_buff *pkt);
160 #endif
161
162 /************************************************************************
163  *  variable declaration
164  ************************************************************************/
165 static smmu_mem_info_t adsl_mem_info[MAX_BAR_REGISTERS];
166 static unsigned long image_size = 0;
167 static struct timeval time_disconnect, time_showtime;
168 static u16 unavailable_seconds = 0;
169 #ifdef IFXMIPS_CLEAR_EOC
170 static wait_queue_head_t wait_queue_hdlc_poll;  ///clear eoc
171 #endif
172
173 static int showtime_lock_flag = 0;
174 static int quiet_mode_flag = 0;
175
176 int showtime = 0;
177 static int major = IFXMIPS_MEI_MAJOR;
178 MEI_mutex_t mei_sema;
179
180 // Mei to ARC CMV count, reply count, ARC Indicator count
181 static int indicator_count = 0;
182 static int cmv_count = 0;
183 static int reply_count = 0;
184 static u16 Recent_indicator[MSG_LENGTH];
185 static int reset_arc_flag = 0;
186
187 // Used in interrupt handler as flags
188 static int arcmsgav = 0;
189 static int cmv_reply = 0;
190 static int cmv_waiting = 0;
191 static int modem_ready = 0;
192 //  to wait for arc cmv reply, sleep on wait_queue_arcmsgav;
193 static wait_queue_head_t wait_queue_arcmsgav;
194
195 // CMV mailbox messages
196 // ARC to MEI message
197 static u16 CMV_RxMsg[MSG_LENGTH] __attribute__ ((aligned (4)));
198 // MEI to ARC message
199 static u16 CMV_TxMsg[MSG_LENGTH] __attribute__ ((aligned (4)));
200
201 static u32 *mei_arc_swap_buff = NULL;   //  holding swap pages
202 static ARC_IMG_HDR *img_hdr;
203 static int arc_halt_flag = 0;
204 static int nBar = 0;            // total bars to be used.
205
206 static u32 loop_diagnostics_mode = 0;
207 wait_queue_head_t wait_queue_loop_diagnostic;
208 int loop_diagnostics_completed = 0;
209 u32 adsl_mode, adsl_mode_extend;        // adsl mode : adsl/ 2/ 2+
210 static int autoboot_enable_flag = 0;
211
212 #ifdef IFX_ADSL_DUAL_LATENCY_SUPPORT
213 static u8 bDualLatency = 0;
214 #endif
215
216 #ifdef IFXMIPS_CLEAR_EOC
217 static u16 ceoc_read_idx = 0;
218 #endif
219
220 #ifdef IFX_ADSL_L3_MODE_SUPPORT
221 static wait_queue_head_t wait_queue_l3; // l3 power mode 
222 static int l3_shutdown = 0;
223 int get_l3_power_status (void);
224 #endif
225
226 #if defined(CONFIG_IFXMIPS_MEI_LED) && defined(DATA_LED_SUPPORT)
227 int led_status_on = 0, led_need_to_flash = 0;
228 static int stop_led_module = 0; //wakeup and clean led module
229 static wait_queue_head_t wait_queue_led_polling;        // adsl led
230 #endif
231
232 static struct file_operations mei_operations = {
233       write : mei_write,
234       ioctl : mei_ioctl,
235 };
236
237 #ifdef CONFIG_PROC_FS
238 static struct proc_dir_entry *meidir;
239 static struct file_operations proc_operations = {
240       read:proc_read,
241       write:proc_write,
242 };
243 static reg_entry_t regs[PROC_ITEMS];    //total items to be monitored by /proc/mei
244 #define NUM_OF_REG_ENTRY        (sizeof(regs)/sizeof(reg_entry_t))
245 #endif //#ifdef CONFIG_PROC_FS
246
247 #ifdef DFE_LOOPBACK
248 unsigned char got_int = 0;
249 #endif
250
251 /////////////////               mei access Rd/Wr methods       ///////////////
252 /**
253  * Write a value to register 
254  * This function writes a value to ifxmips register
255  * 
256  * \param       ul_address      The address to write
257  * \param       ul_data         The value to write
258  * \ingroup     Internal
259  */
260 static void
261 meiLongwordWrite (u32* ul_address, u32 ul_data)
262 {
263         ifxmips_w32(ul_data, ul_address);
264         wmb();
265         return;
266 }                               //    end of "meiLongwordWrite(..."
267
268 /**
269  * Read the ifxmips register 
270  * This function read the value from ifxmips register
271  * 
272  * \param       ul_address      The address to write
273  * \param       pul_data        Pointer to the data
274  * \ingroup     Internal
275  */
276 static void
277 meiLongwordRead (u32* ul_address, u32 * pul_data)
278 {
279         //*pul_data = *((volatile u32 *)ul_address);
280         *pul_data = ifxmips_r32(ul_address);
281         wmb();
282         return;
283 }                               //    end of "meiLongwordRead(..."
284
285 /**
286  * Write several DWORD datas to ARC memory via ARC DMA interface
287  * This function writes several DWORD datas to ARC memory via DMA interface.
288  * 
289  * \param       destaddr        The address to write
290  * \param       databuff        Pointer to the data buffer
291  * \param       databuffsize    Number of DWORDs to write
292  * \return      MEI_SUCCESS or MEI_FAILURE
293  * \ingroup     Internal
294  */
295 static MEI_ERROR
296 meiDMAWrite (u32 destaddr, u32 * databuff, u32 databuffsize)
297 {
298         u32 *p = databuff;
299         u32 temp;
300         MEI_intstat_t flags;
301
302         if (destaddr & 3)
303                 return MEI_FAILURE;
304
305 #ifdef IFXMIPS_DMA_DEBUG_MUTEX
306         MEI_LOCKINT (flags);
307 #endif
308
309         //printk("destaddr=%X,size=%d\n",destaddr,databuffsize);
310         //      Set the write transfer address
311         meiLongwordWrite (MEI_XFR_ADDR, destaddr);
312
313         //      Write the data pushed across DMA
314         while (databuffsize--) {
315                 temp = *p;
316                 if (databuff == (u32 *) CMV_TxMsg)
317                         MEI_HALF_WORD_SWAP (temp);
318                 meiLongwordWrite (MEI_DATA_XFR, temp);
319                 p++;
320         }                       //    end of "while(..."
321
322 #ifdef IFXMIPS_DMA_DEBUG_MUTEX
323         MEI_UNLOCKINT (flags);
324 #endif
325
326         return MEI_SUCCESS;
327
328 }                               //    end of "meiDMAWrite(..."
329
330 /**
331  * Read several DWORD datas from ARC memory via ARC DMA interface
332  * This function reads several DWORD datas from ARC memory via DMA interface.
333  * 
334  * \param       srcaddr         The address to read
335  * \param       databuff        Pointer to the data buffer
336  * \param       databuffsize    Number of DWORDs to read
337  * \return      MEI_SUCCESS or MEI_FAILURE
338  * \ingroup     Internal
339  */
340 static MEI_ERROR
341 meiDMARead (u32 srcaddr, u32 * databuff, u32 databuffsize)
342 {
343         u32 *p = databuff;
344         u32 temp;
345 #ifdef IFXMIPS_DMA_DEBUG_MUTEX
346         MEI_intstat_t flags;
347 #endif
348         //printk("destaddr=%X,size=%X\n",srcaddr,databuffsize);
349         if (srcaddr & 3)
350                 return MEI_FAILURE;
351
352 #ifdef IFXMIPS_DMA_DEBUG_MUTEX
353         MEI_LOCKINT (flags);
354 #endif
355
356         //      Set the read transfer address
357         meiLongwordWrite (MEI_XFR_ADDR, srcaddr);
358
359         //      Read the data popped across DMA
360         while (databuffsize--) {
361                 meiLongwordRead (MEI_DATA_XFR, &temp);
362                 if (databuff == (u32 *) CMV_RxMsg)      // swap half word
363                         MEI_HALF_WORD_SWAP (temp);
364                 *p = temp;
365                 p++;
366         }                       //    end of "while(..."
367
368 #ifdef IFXMIPS_DMA_DEBUG_MUTEX
369         MEI_UNLOCKINT (flags);
370 #endif
371
372         return MEI_SUCCESS;
373
374 }                               //    end of "meiDMARead(..."
375
376 /**
377  * Switch the ARC control mode
378  * This function switchs the ARC control mode to JTAG mode or MEI mode
379  * 
380  * \param       mode            The mode want to switch: JTAG_MASTER_MODE or MEI_MASTER_MODE.
381  * \ingroup     Internal
382  */
383 static void
384 meiControlModeSwitch (int mode)
385 {
386         u32 temp = 0x0;
387         meiLongwordRead ( MEI_DBG_MASTER, &temp);
388         switch (mode) {
389         case JTAG_MASTER_MODE:
390                 temp &= ~(HOST_MSTR);
391                 break;
392         case MEI_MASTER_MODE:
393                 temp |= (HOST_MSTR);
394                 break;
395         default:
396                 printk ("meiControlModeSwitch: unkonwn mode [%d]\n",
397                                  mode);
398                 return;
399         }
400         meiLongwordWrite (MEI_DBG_MASTER, temp);
401 }
402
403 /**
404  * Poll for transaction complete signal
405  * This function polls and waits for transaction complete signal.
406  * 
407  * \ingroup     Internal
408  */
409 static void
410 meiPollForDbgDone (void)
411 {
412         u32 query = 0;
413         int i = 0;
414         while (i < WHILE_DELAY) {
415                 meiLongwordRead (ARC_TO_MEI_INT, &query);
416                 query &= (ARC_TO_MEI_DBG_DONE);
417                 if (query)
418                         break;
419                 i++;
420                 if (i == WHILE_DELAY) {
421                         printk ("\n\n PollforDbg fail");
422                 }
423         }
424         meiLongwordWrite ( ARC_TO_MEI_INT, ARC_TO_MEI_DBG_DONE);        // to clear this interrupt
425 }                               //    end of "meiPollForDbgDone(..."
426
427 /**
428  * ARC Debug Memory Access for a single DWORD reading.
429  * This function used for direct, address-based access to ARC memory.
430  * 
431  * \param       DEC_mode        ARC memory space to used
432  * \param       address         Address to read
433  * \param       data            Pointer to data
434  * \return      MEI_SUCCESS or MEI_FAILURE
435  * \ingroup     Internal
436  */
437 static MEI_ERROR
438 _meiDebugLongWordRead (u32 DEC_mode, u32 address, u32 * data)
439 {
440         meiLongwordWrite ( MEI_DEBUG_DEC, DEC_mode);
441         meiLongwordWrite ( MEI_DEBUG_RAD, address);
442         meiPollForDbgDone ();
443         meiLongwordRead (MEI_DEBUG_DATA, data);
444         return MEI_SUCCESS;
445 }
446
447 /**
448  * ARC Debug Memory Access for a single DWORD writing.
449  * This function used for direct, address-based access to ARC memory.
450  * 
451  * \param       DEC_mode        ARC memory space to used
452  * \param       address         The address to write
453  * \param       data            The data to write
454  * \return      MEI_SUCCESS or MEI_FAILURE
455  * \ingroup     Internal
456  */
457 static MEI_ERROR
458 _meiDebugLongWordWrite (u32 DEC_mode, u32 address, u32 data)
459 {
460         meiLongwordWrite (MEI_DEBUG_DEC, DEC_mode);
461         meiLongwordWrite (MEI_DEBUG_WAD, address);
462         meiLongwordWrite (MEI_DEBUG_DATA, data);
463         meiPollForDbgDone ();
464         return MEI_SUCCESS;
465 }
466
467 /**
468  * ARC Debug Memory Access for writing.
469  * This function used for direct, address-based access to ARC memory.
470  * 
471  * \param       destaddr        The address to ead
472  * \param       databuffer      Pointer to data
473  * \param       databuffsize    The number of DWORDs to read
474  * \return      MEI_SUCCESS or MEI_FAILURE
475  * \ingroup     Internal
476  */
477
478 MEI_ERROR
479 meiDebugWrite (u32 destaddr, u32 * databuff, u32 databuffsize)
480 {
481         u32 i;
482         u32 temp = 0x0;
483         u32 address = 0x0;
484         u32 *buffer = 0x0;
485 #ifdef IFXMIPS_DMA_DEBUG_MUTEX
486         MEI_intstat_t flags;
487 #endif
488
489 #ifdef IFXMIPS_DMA_DEBUG_MUTEX
490         MEI_LOCKINT (flags);
491 #endif
492
493         //      Open the debug port before DMP memory write
494         meiControlModeSwitch (MEI_MASTER_MODE);
495
496         meiLongwordWrite (MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP1_MASK);
497
498         //      For the requested length, write the address and write the data
499         address = destaddr;
500         buffer = databuff;
501         for (i = 0; i < databuffsize; i++) {
502                 temp = *buffer;
503                 _meiDebugLongWordWrite (MEI_DEBUG_DEC_DMP1_MASK, address,
504                                         temp);
505                 address += 4;
506                 buffer++;
507         }                       //    end of "for(..."
508
509         //      Close the debug port after DMP memory write
510         meiControlModeSwitch (JTAG_MASTER_MODE);
511
512 #ifdef IFXMIPS_DMA_DEBUG_MUTEX
513         MEI_UNLOCKINT (flags);
514 #endif
515
516         //      Return
517         return MEI_SUCCESS;
518
519 }                               //    end of "meiDebugWrite(..."
520
521 /**
522  * ARC Debug Memory Access for reading.
523  * This function used for direct, address-based access to ARC memory.
524  * 
525  * \param       srcaddr         The address to read
526  * \param       databuffer      Pointer to data
527  * \param       databuffsize    The number of DWORDs to read
528  * \return      MEI_SUCCESS or MEI_FAILURE
529  * \ingroup     Internal
530  */
531 static MEI_ERROR
532 meiDebugRead (u32 srcaddr, u32 * databuff, u32 databuffsize)
533 {
534         u32 i;
535         u32 temp = 0x0;
536         u32 address = 0x0;
537         u32 *buffer = 0x0;
538 #ifdef IFXMIPS_DMA_DEBUG_MUTEX
539         MEI_intstat_t flags;
540 #endif
541
542 #ifdef IFXMIPS_DMA_DEBUG_MUTEX
543         MEI_LOCKINT (flags);
544 #endif
545
546         //      Open the debug port before DMP memory read
547         meiControlModeSwitch (MEI_MASTER_MODE);
548
549         meiLongwordWrite (MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP1_MASK);
550
551         //      For the requested length, write the address and read the data
552         address = srcaddr;
553         buffer = databuff;
554         for (i = 0; i < databuffsize; i++) {
555                 _meiDebugLongWordRead (MEI_DEBUG_DEC_DMP1_MASK, address,
556                                        &temp);
557                 *buffer = temp;
558                 address += 4;
559                 buffer++;
560         }                       //    end of "for(..."
561
562         //      Close the debug port after DMP memory read
563         meiControlModeSwitch (JTAG_MASTER_MODE);
564
565 #ifdef IFXMIPS_DMA_DEBUG_MUTEX
566         MEI_UNLOCKINT (flags);
567 #endif
568
569         //      Return
570         return MEI_SUCCESS;
571
572 }                               //    end of "meiDebugRead(..."
573
574 /**
575  * Send a message to ARC MailBox.
576  * This function sends a message to ARC Mailbox via ARC DMA interface.
577  * 
578  * \param       msgsrcbuffer    Pointer to message.
579  * \param       msgsize         The number of words to write.
580  * \return      MEI_SUCCESS or MEI_FAILURE
581  * \ingroup     Internal
582  */
583 static MEI_ERROR
584 meiMailboxWrite (u16 * msgsrcbuffer, u16 msgsize)
585 {
586         int i;
587         u32 arc_mailbox_status = 0x0;
588         u32 temp = 0;
589         MEI_ERROR meiMailboxError = MEI_SUCCESS;
590
591         //      Write to mailbox
592         meiMailboxError =
593                 meiDMAWrite (MEI_TO_ARC_MAILBOX, (u32 *) msgsrcbuffer,
594                              msgsize / 2);
595         meiMailboxError =
596                 meiDMAWrite (MEI_TO_ARC_MAILBOXR, (u32 *) (&temp), 1);
597
598         //      Notify arc that mailbox write completed
599         cmv_waiting = 1;
600         meiLongwordWrite (MEI_TO_ARC_INT, MEI_TO_ARC_MSGAV);
601
602         i = 0;
603         while (i < WHILE_DELAY) {       // wait for ARC to clear the bit
604                 meiLongwordRead ( MEI_TO_ARC_INT, &arc_mailbox_status);
605                 if ((arc_mailbox_status & MEI_TO_ARC_MSGAV) !=
606                     MEI_TO_ARC_MSGAV)
607                         break;
608                 i++;
609                 if (i == WHILE_DELAY) {
610                         printk
611                                 ("\n\n MEI_TO_ARC_MSGAV not cleared by ARC");
612                         meiMailboxError = MEI_FAILURE;
613                 }
614         }
615
616         //      Return
617         return meiMailboxError;
618
619 }                               //    end of "meiMailboxWrite(..."
620
621 /**
622  * Read a message from ARC MailBox.
623  * This function reads a message from ARC Mailbox via ARC DMA interface.
624  * 
625  * \param       msgsrcbuffer    Pointer to message.
626  * \param       msgsize         The number of words to read
627  * \return      MEI_SUCCESS or MEI_FAILURE
628  * \ingroup     Internal
629  */
630 static MEI_ERROR
631 meiMailboxRead (u16 * msgdestbuffer, u16 msgsize)
632 {
633         MEI_ERROR meiMailboxError = MEI_SUCCESS;
634         //      Read from mailbox
635         meiMailboxError =
636                 meiDMARead (ARC_TO_MEI_MAILBOX, (u32 *) msgdestbuffer,
637                             msgsize / 2);
638
639         //      Notify arc that mailbox read completed
640         meiLongwordWrite (ARC_TO_MEI_INT, ARC_TO_MEI_MSGAV);
641
642         //      Return
643         return meiMailboxError;
644
645 }                               //    end of "meiMailboxRead(..."
646
647 /**
648  * Download boot pages to ARC.
649  * This function downloads boot pages to ARC.
650  * 
651  * \return      MEI_SUCCESS or MEI_FAILURE
652  * \ingroup     Internal
653  */
654 static MEI_ERROR
655 meiDownloadBootPages (void)
656 {
657         int boot_loop;
658         int page_size;
659         u32 dest_addr;
660
661         /*
662          **     DMA the boot code page(s)
663          */
664 #ifndef HEADER_SWAP
665         for (boot_loop = 1; boot_loop < le32_to_cpu (img_hdr->count);
666              boot_loop++)
667 #else
668         for (boot_loop = 1; boot_loop < (img_hdr->count); boot_loop++)
669 #endif
670         {
671 #ifndef HEADER_SWAP
672                 if (le32_to_cpu (img_hdr->page[boot_loop].p_size) & BOOT_FLAG)
673 #else
674                 if ((img_hdr->page[boot_loop].p_size) & BOOT_FLAG)
675 #endif
676                 {
677                         page_size =
678                                 meiGetPage (boot_loop, GET_PROG, MAXSWAPSIZE,
679                                             mei_arc_swap_buff, &dest_addr);
680                         if (page_size > 0) {
681                                 meiDMAWrite (dest_addr, mei_arc_swap_buff,
682                                              page_size);
683                         }
684                 }
685 #ifndef HEADER_SWAP
686                 if (le32_to_cpu (img_hdr->page[boot_loop].d_size) & BOOT_FLAG)
687 #else
688                 if ((img_hdr->page[boot_loop].d_size) & BOOT_FLAG)
689 #endif
690                 {
691                         page_size =
692                                 meiGetPage (boot_loop, GET_DATA, MAXSWAPSIZE,
693                                             mei_arc_swap_buff, &dest_addr);
694                         if (page_size > 0) {
695                                 meiDMAWrite (dest_addr, mei_arc_swap_buff,
696                                              page_size);
697                         }
698                 }
699         }
700         return MEI_SUCCESS;
701 }
702
703 /**
704  * Initial efuse rar.
705  **/
706 static void
707 mei_fuse_rar_init (void)
708 {
709         u32 data = 0;
710         meiDMAWrite (IRAM0_BASE, &data, 1);
711         meiDMAWrite (IRAM0_BASE + 4, &data, 1);
712         meiDMAWrite (IRAM1_BASE, &data, 1);
713         meiDMAWrite (IRAM1_BASE + 4, &data, 1);
714         meiDMAWrite (BRAM_BASE, &data, 1);
715         meiDMAWrite (BRAM_BASE + 4, &data, 1);
716         meiDMAWrite (ADSL_DILV_BASE, &data, 1);
717         meiDMAWrite (ADSL_DILV_BASE + 4, &data, 1);
718 }
719
720 /**
721  * efuse rar program
722  **/
723 static void
724 mei_fuse_prg (void)
725 {
726         u32 reg_data, fuse_value;
727         int i = 0;
728         meiLongwordRead ( IFXMIPS_RCU_RST, &reg_data);
729         while ((reg_data & 0x10000000) == 0) {
730                 meiLongwordRead ( IFXMIPS_RCU_RST, &reg_data);
731                 //add a watchdog
732                 i++;
733                 /* 0x4000 translate to  about 16 ms@111M, so should be enough */
734                 if (i == 0x4000)
735                         return;
736         }
737         // STEP a: Prepare memory for external accesses
738         // Write fuse_en bit24
739         meiLongwordRead (IFXMIPS_RCU_RST, &reg_data);
740         meiLongwordWrite (IFXMIPS_RCU_RST, reg_data | (1 << 24));
741
742         mei_fuse_rar_init ();
743         for (i = 0; i < 4; i++) {
744                 meiLongwordRead((u32*)(IFXMIPS_FUSE_BASE_ADDR + (i * 4)), &fuse_value);
745                 switch (fuse_value & 0xF0000) {
746                 case 0x80000:
747                         reg_data =
748                                 ((fuse_value & RX_DILV_ADDR_BIT_MASK) |
749                                  (RX_DILV_ADDR_BIT_MASK + 0x1));
750                         meiDMAWrite (ADSL_DILV_BASE, &reg_data, 1);
751                         break;
752                 case 0x90000:
753                         reg_data =
754                                 ((fuse_value & RX_DILV_ADDR_BIT_MASK) |
755                                  (RX_DILV_ADDR_BIT_MASK + 0x1));
756                         meiDMAWrite (ADSL_DILV_BASE + 4, &reg_data, 1);
757                         break;
758                 case 0xA0000:
759                         reg_data =
760                                 ((fuse_value & IRAM0_ADDR_BIT_MASK) |
761                                  (IRAM0_ADDR_BIT_MASK + 0x1));
762                         meiDMAWrite (IRAM0_BASE, &reg_data, 1);
763                         break;
764                 case 0xB0000:
765                         reg_data =
766                                 ((fuse_value & IRAM0_ADDR_BIT_MASK) |
767                                  (IRAM0_ADDR_BIT_MASK + 0x1));
768                         meiDMAWrite (IRAM0_BASE + 4, &reg_data, 1);
769                         break;
770                 case 0xC0000:
771                         reg_data =
772                                 ((fuse_value & IRAM1_ADDR_BIT_MASK) |
773                                  (IRAM1_ADDR_BIT_MASK + 0x1));
774                         meiDMAWrite (IRAM1_BASE, &reg_data, 1);
775                         break;
776                 case 0xD0000:
777                         reg_data =
778                                 ((fuse_value & IRAM1_ADDR_BIT_MASK) |
779                                  (IRAM1_ADDR_BIT_MASK + 0x1));
780                         meiDMAWrite (IRAM1_BASE + 4, &reg_data, 1);
781                         break;
782                 case 0xE0000:
783                         reg_data =
784                                 ((fuse_value & BRAM_ADDR_BIT_MASK) |
785                                  (BRAM_ADDR_BIT_MASK + 0x1));
786                         meiDMAWrite (BRAM_BASE, &reg_data, 1);
787                         break;
788                 case 0xF0000:
789                         reg_data =
790                                 ((fuse_value & BRAM_ADDR_BIT_MASK) |
791                                  (BRAM_ADDR_BIT_MASK + 0x1));
792                         meiDMAWrite (BRAM_BASE + 4, &reg_data, 1);
793                         break;
794                 default:        // PPE efuse
795                         break;
796                 }
797         }
798         meiLongwordRead (IFXMIPS_RCU_RST, &reg_data);
799         meiLongwordWrite (IFXMIPS_RCU_RST, reg_data & 0xF7FFFFFF);
800 }
801
802 /**
803  * Download boot code to ARC.
804  * This function downloads boot code to ARC.
805  * 
806  * \return      MEI_SUCCESS or MEI_FAILURE
807  * \ingroup     Internal
808  */
809 static MEI_ERROR
810 meiDownloadBootCode (void)
811 {
812         u32 arc_debug_data = ACL_CLK_MODE_ENABLE;       //0x10
813
814         meiMailboxInterruptsDisable ();
815
816         //      Switch arc control from JTAG mode to MEI mode
817         meiControlModeSwitch (MEI_MASTER_MODE);
818         //enable ac_clk signal  
819         _meiDebugLongWordRead (MEI_DEBUG_DEC_DMP1_MASK, CRI_CCR0,
820                                &arc_debug_data);
821         arc_debug_data |= ACL_CLK_MODE_ENABLE;
822         _meiDebugLongWordWrite (MEI_DEBUG_DEC_DMP1_MASK, CRI_CCR0,
823                                 arc_debug_data);
824         //Switch arc control from MEI mode to JTAG mode
825         meiControlModeSwitch (JTAG_MASTER_MODE);
826
827         mei_fuse_prg ();        //program fuse rar
828
829         meiDownloadBootPages ();
830
831         return MEI_SUCCESS;
832
833 }                               //    end of "meiDownloadBootCode(..."
834
835 //#endif
836
837 /**
838  * Halt the ARC.
839  * This function halts the ARC.
840  * 
841  * \return      MEI_SUCCESS or MEI_FAILURE
842  * \ingroup     Internal
843  */
844 static MEI_ERROR
845 meiHaltArc (void)
846 {
847         u32 arc_debug_data = 0x0;
848
849         //      Switch arc control from JTAG mode to MEI mode
850         meiControlModeSwitch (MEI_MASTER_MODE);
851         _meiDebugLongWordRead (MEI_DEBUG_DEC_AUX_MASK, ARC_DEBUG,
852                                &arc_debug_data);
853         arc_debug_data |= (BIT1);
854         _meiDebugLongWordWrite (MEI_DEBUG_DEC_AUX_MASK, ARC_DEBUG,
855                                 arc_debug_data);
856         //      Switch arc control from MEI mode to JTAG mode
857         meiControlModeSwitch (JTAG_MASTER_MODE);
858         arc_halt_flag = 1;
859
860         MEI_WAIT (10);
861         //      Return
862         return MEI_SUCCESS;
863
864 }                               //    end of "meiHalt(..."
865
866 /**
867  * Run the ARC.
868  * This function runs the ARC.
869  * 
870  * \return      MEI_SUCCESS or MEI_FAILURE
871  * \ingroup     Internal
872  */
873 static MEI_ERROR
874 meiRunArc (void)
875 {
876         u32 arc_debug_data = 0x0;
877
878         //      Switch arc control from JTAG mode to MEI mode- write '1' to bit0
879         meiControlModeSwitch (MEI_MASTER_MODE);
880         _meiDebugLongWordRead (MEI_DEBUG_DEC_AUX_MASK, AUX_STATUS,
881                                &arc_debug_data);
882
883         //      Write debug data reg with content ANDd with 0xFDFFFFFF (halt bit cleared)
884         arc_debug_data &= ~(BIT25);
885         _meiDebugLongWordWrite (MEI_DEBUG_DEC_AUX_MASK, AUX_STATUS,
886                                 arc_debug_data);
887
888         //      Switch arc control from MEI mode to JTAG mode- write '0' to bit0
889         meiControlModeSwitch (JTAG_MASTER_MODE);
890         //      Enable mask for arc codeswap interrupts
891         meiMailboxInterruptsEnable ();
892         arc_halt_flag = 0;
893
894         //      Return
895         return MEI_SUCCESS;
896
897 }                               //    end of "meiActivate(..."
898
899 /**
900  * Reset the ARC.
901  * This function resets the ARC.
902  * 
903  * \return      MEI_SUCCESS or MEI_FAILURE
904  * \ingroup     Internal
905  */
906 static MEI_ERROR
907 meiResetARC (void)
908 {
909
910         u32 arc_debug_data = 0;
911         showtime = 0;
912
913         meiHaltArc ();
914
915         meiLongwordRead (IFXMIPS_RCU_RST, &arc_debug_data);
916         meiLongwordWrite (IFXMIPS_RCU_RST,
917                           arc_debug_data | IFXMIPS_RCU_RST_REQ_DFE |
918                           IFXMIPS_RCU_RST_REQ_AFE);
919         meiLongwordWrite (IFXMIPS_RCU_RST, arc_debug_data);
920         // reset ARC
921         meiLongwordWrite(MEI_RST_CONTROL, MEI_SOFT_RESET);
922         meiLongwordWrite(MEI_RST_CONTROL, 0);
923
924         meiMailboxInterruptsDisable ();
925         MEI_MUTEX_INIT (mei_sema, 1);
926         reset_arc_flag = 1;
927         modem_ready = 0;
928         return MEI_SUCCESS;
929 }
930
931 /**
932  * Reset the ARC, download boot codes, and run the ARC.
933  * This function resets the ARC, downloads boot codes to ARC, and runs the ARC.
934  * 
935  * \return      MEI_SUCCESS or MEI_FAILURE
936  * \ingroup     Internal
937  */
938 static MEI_ERROR
939 meiRunAdslModem (void)
940 {
941         int nSize = 0, idx = 0;
942
943         img_hdr = (ARC_IMG_HDR *) adsl_mem_info[0].address;
944 #if     defined(HEADER_SWAP)
945         if ((img_hdr->count) * sizeof (ARC_SWP_PAGE_HDR) > SDRAM_SEGMENT_SIZE)
946 #else //define(HEADER_SWAP)
947         if (le32_to_cpu (img_hdr->count) * sizeof (ARC_SWP_PAGE_HDR) >
948             SDRAM_SEGMENT_SIZE)
949 #endif //define(HEADER_SWAP)
950         {
951                 printk
952                         ("segment_size is smaller than firmware header size\n");
953                 return -1;
954         }
955         // check image size 
956         for (idx = 0; idx < MAX_BAR_REGISTERS; idx++) {
957                 nSize += adsl_mem_info[idx].nCopy;
958         }
959         if (nSize != image_size) {
960                 printk
961                         ("Firmware download is not completed. \nPlease download firmware again!\n");
962                 return -1;
963         }
964         // TODO: check crc
965         ///
966         if (reset_arc_flag == 0) {
967                 u32 arc_debug_data;
968
969                 meiResetARC ();
970                 meiControlModeSwitch (MEI_MASTER_MODE);
971                 //enable ac_clk signal  
972                 _meiDebugLongWordRead (MEI_DEBUG_DEC_DMP1_MASK, CRI_CCR0,
973                                        &arc_debug_data);
974                 arc_debug_data |= ACL_CLK_MODE_ENABLE;
975                 _meiDebugLongWordWrite (MEI_DEBUG_DEC_DMP1_MASK, CRI_CCR0,
976                                         arc_debug_data);
977                 meiControlModeSwitch (JTAG_MASTER_MODE);
978                 meiHaltArc ();
979                 update_bar_register (nBar);
980         }
981         reset_arc_flag = 0;
982         if (arc_halt_flag == 0) {
983                 meiHaltArc ();
984         }
985         printk ("Starting to meiDownloadBootCode\n");
986
987         meiDownloadBootCode();
988  
989         // 1.00.09  20/12/2006 TC Chen
990         // disable USB OC interrupt, reset DSL chip will triger OC interrupt
991         disable_irq(IFXMIPS_USB_OC_INT);
992
993         meiRunArc ();
994
995         MEI_WAIT (100);         //wait 100ms 
996
997         //1.00.09  20/12/2006 TC Chen
998         // restore USB OC interrupt
999         MEI_MASK_AND_ACK_IRQ(IFXMIPS_USB_OC_INT);
1000         enable_irq(IFXMIPS_USB_OC_INT);
1001
1002         if (modem_ready != 1) {
1003                 printk ("Running ADSL modem firmware fail!\n");
1004                 return MEI_FAILURE;
1005         }
1006
1007
1008         return MEI_SUCCESS;
1009 }
1010
1011 /**
1012  * Get the page's data pointer
1013  * This function caculats the data address from the firmware header.
1014  * 
1015  * \param       Page            The page number.
1016  * \param       data            Data page or program page.
1017  * \param       MaxSize         The maximum size to read.
1018  * \param       Buffer          Pointer to data.
1019  * \param       Dest            Pointer to the destination address.
1020  * \return      The number of bytes to read.
1021  * \ingroup     Internal
1022  */
1023 static int
1024 meiGetPage (u32 Page, u32 data, u32 MaxSize, u32 * Buffer, u32 * Dest)
1025 {
1026         u32 size;
1027         u32 i;
1028         u32 *p;
1029         u32 idx, offset, nBar = 0;
1030
1031         if (Page > img_hdr->count)
1032                 return -2;
1033         /*
1034          **     Get program or data size, depending on "data" flag
1035          */
1036 #ifndef HEADER_SWAP
1037         size = (data ==
1038                 GET_DATA) ? le32_to_cpu (img_hdr->page[Page].
1039                                          d_size) : le32_to_cpu (img_hdr->
1040                                                                 page[Page].
1041                                                                 p_size);
1042 #else
1043         size = (data ==
1044                 GET_DATA) ? (img_hdr->page[Page].d_size) : (img_hdr->
1045                                                             page[Page].
1046                                                             p_size);
1047 #endif
1048         size &= BOOT_FLAG_MASK; //      Clear boot bit!
1049         if (size > MaxSize)
1050                 return -1;
1051
1052         if (size == 0)
1053                 return 0;
1054         /*
1055          **     Get program or data offset, depending on "data" flag
1056          */
1057 #ifndef HEADER_SWAP
1058         i = data ? le32_to_cpu (img_hdr->page[Page].
1059                                 d_offset) : le32_to_cpu (img_hdr->page[Page].
1060                                                          p_offset);
1061 #else
1062         i = data ? (img_hdr->page[Page].d_offset) : (img_hdr->page[Page].
1063                                                      p_offset);
1064 #endif
1065
1066         /*
1067          **     Copy data/program to buffer
1068          */
1069
1070         idx = i / SDRAM_SEGMENT_SIZE;
1071         offset = i % SDRAM_SEGMENT_SIZE;
1072         p = (u32 *) ((u8 *) adsl_mem_info[idx].address + offset);
1073
1074         for (i = 0; i < size; i++) {
1075                 if (offset + i * 4 - (nBar * SDRAM_SEGMENT_SIZE) >=
1076                     SDRAM_SEGMENT_SIZE) {
1077                         idx++;
1078                         nBar++;
1079                         p = (u32 *) ((u8 *)
1080                                      KSEG1ADDR ((u32) adsl_mem_info[idx].
1081                                                 address));
1082                 }
1083                 Buffer[i] = *p++;
1084 #ifdef BOOT_SWAP
1085 #ifndef IMAGE_SWAP
1086                 Buffer[i] = le32_to_cpu (Buffer[i]);
1087 #endif
1088 #endif
1089         }
1090
1091         /*
1092          **     Pass back data/program destination address
1093          */
1094 #ifndef HEADER_SWAP
1095         *Dest = data ? le32_to_cpu (img_hdr->page[Page].
1096                                     d_dest) : le32_to_cpu (img_hdr->
1097                                                            page[Page].p_dest);
1098 #else
1099         *Dest = data ? (img_hdr->page[Page].d_dest) : (img_hdr->page[Page].
1100                                                        p_dest);
1101 #endif
1102
1103         return size;
1104 }
1105
1106 ////////////////makeCMV(Opcode, Group, Address, Index, Size, Data), CMV in u16 TxMessage[MSG_LENGTH]///////////////////////////
1107
1108 /**
1109  * Compose a message.
1110  * This function compose a message from opcode, group, address, index, size, and data
1111  * 
1112  * \param       opcode          The message opcode
1113  * \param       group           The message group number
1114  * \param       address         The message address.
1115  * \param       index           The message index.
1116  * \param       size            The number of words to read/write.
1117  * \param       data            The pointer to data.
1118  * \param       CMVMSG          The pointer to message buffer.
1119  * \ingroup     Internal
1120  */
1121 void
1122 makeCMV (u8 opcode, u8 group, u16 address, u16 index, int size, u16 * data,
1123          u16 * CMVMSG)
1124 {
1125         memset (CMVMSG, 0, MSG_LENGTH * 2);
1126         CMVMSG[0] = (opcode << 4) + (size & 0xf);
1127         CMVMSG[1] = (((index == 0) ? 0 : 1) << 7) + (group & 0x7f);
1128         CMVMSG[2] = address;
1129         CMVMSG[3] = index;
1130         if (opcode == H2D_CMV_WRITE)
1131                 memcpy (CMVMSG + 4, data, size * 2);
1132         return;
1133 }
1134
1135 /**
1136  * Send a message to ARC and read the response
1137  * This function sends a message to arc, waits the response, and reads the responses.
1138  * 
1139  * \param       request         Pointer to the request
1140  * \param       reply           Wait reply or not.
1141  * \param       response        Pointer to the response
1142  * \return      MEI_SUCCESS or MEI_FAILURE
1143  * \ingroup     Internal
1144  */
1145 MEI_ERROR
1146 meiCMV (u16 * request, int reply, u16 * response)       // write cmv to arc, if reply needed, wait for reply
1147 {
1148         MEI_ERROR meierror;
1149 #if defined(IFXMIPS_PORT_RTEMS)
1150         int delay_counter = 0;
1151 #endif
1152
1153         cmv_reply = reply;
1154         memcpy (CMV_TxMsg, request, MSG_LENGTH * 2);
1155         arcmsgav = 0;
1156
1157         meierror = meiMailboxWrite (CMV_TxMsg, MSG_LENGTH);
1158
1159         if (meierror != MEI_SUCCESS) {
1160                 cmv_waiting = 0;
1161                 arcmsgav = 0;
1162                 printk ("\n\n MailboxWrite Fail.");
1163                 return meierror;
1164         }
1165         else {
1166                 cmv_count++;
1167         }
1168
1169         if (cmv_reply == NO_REPLY)
1170                 return MEI_SUCCESS;
1171
1172 #if !defined(IFXMIPS_PORT_RTEMS)
1173         if (arcmsgav == 0)
1174                 MEI_WAIT_EVENT_TIMEOUT (wait_queue_arcmsgav, CMV_TIMEOUT);
1175 #else
1176         while (arcmsgav == 0 && delay_counter < CMV_TIMEOUT / 5) {
1177                 MEI_WAIT (5);
1178                 delay_counter++;
1179         }
1180 #endif
1181
1182         cmv_waiting = 0;
1183         if (arcmsgav == 0) {    //CMV_timeout
1184                 arcmsgav = 0;
1185                 printk ("\nmeiCMV: MEI_MAILBOX_TIMEOUT\n");
1186                 return MEI_MAILBOX_TIMEOUT;
1187         }
1188         else {
1189                 arcmsgav = 0;
1190                 reply_count++;
1191                 memcpy (response, CMV_RxMsg, MSG_LENGTH * 2);
1192                 return MEI_SUCCESS;
1193         }
1194         return MEI_SUCCESS;
1195 }
1196
1197 /////////////////////          Interrupt handler     /////////////////////////
1198 /**
1199  * Disable ARC to MEI interrupt
1200  * 
1201  * \ingroup     Internal
1202  */
1203 static void
1204 meiMailboxInterruptsDisable (void)
1205 {
1206         meiLongwordWrite (ARC_TO_MEI_INT_MASK, 0x0);
1207 }                               //    end of "meiMailboxInterruptsDisable(..."
1208
1209 /**
1210  * Eable ARC to MEI interrupt
1211  * 
1212  * \ingroup     Internal
1213  */
1214 static void
1215 meiMailboxInterruptsEnable (void)
1216 {
1217         meiLongwordWrite (ARC_TO_MEI_INT_MASK, MSGAV_EN);
1218 }                               //    end of "meiMailboxInterruptsEnable(..."
1219
1220 /**
1221  * MEI interrupt handler
1222  * 
1223  * \param int1  
1224  * \param void0
1225  * \param regs  Pointer to the structure of ifxmips mips registers
1226  * \ingroup     Internal
1227  */
1228 irqreturn_t
1229 mei_interrupt_arcmsgav (int int1, void *void0)
1230 {
1231         u32 scratch;
1232
1233 #if defined(DFE_LOOPBACK) && defined(DFE_PING_TEST)
1234         dfe_loopback_irq_handler ();
1235         goto out;
1236 #endif //DFE_LOOPBACK
1237
1238         meiDebugRead (ARC_MEI_MAILBOXR, &scratch, 1);
1239         if (scratch & OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK) {
1240                 printk("\n\n Receive Code Swap Request interrupt!!!");
1241                 goto out;
1242         }
1243         else if (scratch & OMB_CLEAREOC_INTERRUPT_CODE) // clear eoc message interrupt
1244         {
1245                 meiLongwordWrite (ARC_TO_MEI_INT, ARC_TO_MEI_MSGAV);
1246 #if defined (IFXMIPS_CLEAR_EOC)
1247                 MEI_WAKEUP_EVENT (wait_queue_hdlc_poll);
1248 #endif
1249                 MEI_MASK_AND_ACK_IRQ (IFXMIPS_MEI_INT);
1250                 goto out;
1251         }
1252         else {                  // normal message
1253                 meiMailboxRead (CMV_RxMsg, MSG_LENGTH);
1254 #if 0
1255                 {
1256                         int msg_idx = 0;
1257                         printk ("got interrupt\n");
1258                         for (msg_idx = 0; msg_idx < MSG_LENGTH; msg_idx++) {
1259                                 printk ("%04X ", CMV_RxMsg[msg_idx]);
1260                                 if (msg_idx % 8 == 7)
1261                                         printk ("\n");
1262                         }
1263                         printk ("\n");
1264                 }
1265 #endif
1266                 if (cmv_waiting == 1) {
1267                         arcmsgav = 1;
1268                         cmv_waiting = 0;
1269 #if !defined(IFXMIPS_PORT_RTEMS)
1270                         MEI_WAKEUP_EVENT (wait_queue_arcmsgav);
1271 #endif
1272                 }
1273                 else {
1274                         indicator_count++;
1275                         memcpy ((char *) Recent_indicator, (char *) CMV_RxMsg,
1276                                 MSG_LENGTH * 2);
1277                         if (((CMV_RxMsg[0] & 0xff0) >> 4) == D2H_AUTONOMOUS_MODEM_READY_MSG)    // arc ready
1278                         {       //check ARC ready message
1279                                 printk ("Got MODEM_READY_MSG\n");
1280                                 modem_ready = 1;
1281                                 MEI_MUTEX_UNLOCK (mei_sema);    // allow cmv access
1282                         }
1283                 }
1284         }
1285
1286         MEI_MASK_AND_ACK_IRQ (IFXMIPS_MEI_INT);
1287 out:
1288         return IRQ_HANDLED;;
1289 }
1290
1291 ////////////////////////hdlc ////////////////
1292
1293 /**
1294  * Get the hdlc status
1295  * 
1296  * \return      HDLC status
1297  * \ingroup     Internal
1298  */
1299 static unsigned int
1300 ifx_me_hdlc_status (void)
1301 {
1302         u16 CMVMSG[MSG_LENGTH];
1303         int ret;
1304
1305         if (showtime != 1)
1306                 return -ENETRESET;
1307
1308         makeCMV (H2D_CMV_READ, STAT, 14, 0, 1, NULL, CMVMSG);   //Get HDLC status 
1309         ret = mei_ioctl ((struct inode *) 0, NULL, IFXMIPS_MEI_CMV_WINHOST,
1310                          (unsigned long) CMVMSG);
1311         if (ret != 0) {
1312                 return -EIO;
1313         }
1314         return CMVMSG[4] & 0x0F;
1315 }
1316
1317 /**
1318  * Check if the me is reslved.
1319  * 
1320  * \param       status          the me status
1321  * \return      ME_HDLC_UNRESOLVED or ME_HDLC_RESOLVED
1322  * \ingroup     Internal
1323  */
1324 int
1325 ifx_me_is_resloved (int status)
1326 {
1327         u16 CMVMSG[MSG_LENGTH];
1328         int ret;
1329         if (adsl_mode <= 8 && adsl_mode_extend == 0)    // adsl mode
1330         {
1331                 makeCMV (H2D_CMV_READ, CNTL, 2, 0, 1, NULL, CMVMSG);    //Get ME-HDLC Control
1332                 ret = mei_ioctl ((struct inode *) 0, NULL,
1333                                  IFXMIPS_MEI_CMV_WINHOST,
1334                                  (unsigned long) CMVMSG);
1335                 if (ret != 0) {
1336                         return ME_HDLC_UNRESOLVED;
1337                 }
1338                 if (CMVMSG[4] & (1 << 0)) {
1339                         return ME_HDLC_UNRESOLVED;
1340                 }
1341         }
1342         else {
1343                 if (status == ME_HDLC_MSG_QUEUED
1344                     || status == ME_HDLC_MSG_SENT)
1345                         return ME_HDLC_UNRESOLVED;
1346                 if (status == ME_HDLC_IDLE) {
1347                         makeCMV (H2D_CMV_READ, CNTL, 2, 0, 1, NULL, CMVMSG);    //Get ME-HDLC Control
1348                         ret = mei_ioctl ((struct inode *) 0, NULL,
1349                                          IFXMIPS_MEI_CMV_WINHOST,
1350                                          (unsigned long) CMVMSG);
1351                         if (ret != 0) {
1352                                 return IFX_POP_EOC_FAIL;
1353                         }
1354                         if (CMVMSG[4] & (1 << 0)) {
1355                                 return ME_HDLC_UNRESOLVED;
1356                         }
1357                 }
1358         }
1359         return ME_HDLC_RESOLVED;
1360 }
1361
1362 int
1363 _ifx_me_hdlc_send (unsigned char *hdlc_pkt, int pkt_len, int max_length)
1364 {
1365         int ret;
1366         u16 CMVMSG[MSG_LENGTH];
1367         u16 data = 0;
1368         u16 len = 0;
1369         int rx_length = 0;
1370         int write_size = 0;
1371
1372         if (pkt_len > max_length) {
1373                 makeCMV (H2D_CMV_READ, INFO, 85, 2, 1, NULL, CMVMSG);   //Get ME-HDLC Control
1374                 ret = mei_ioctl ((struct inode *) 0, NULL,
1375                                  IFXMIPS_MEI_CMV_WINHOST,
1376                                  (unsigned long) CMVMSG);
1377                 if (ret != 0) {
1378                         return -EIO;
1379                 }
1380                 rx_length = CMVMSG[4];
1381                 if (rx_length + max_length < pkt_len) {
1382                         printk ("Exceed maximum eoc rx(%d)+tx(%d) message length\n", rx_length, max_length);
1383                         return -EMSGSIZE;
1384                 }
1385                 data = 1;
1386                 makeCMV (H2D_CMV_WRITE, INFO, 85, 6, 1, &data, CMVMSG); //disable RX Eoc
1387                 ret = mei_ioctl ((struct inode *) 0, NULL,
1388                                  IFXMIPS_MEI_CMV_WINHOST,
1389                                  (unsigned long) CMVMSG);
1390                 if (ret != 0) {
1391                         return -EIO;
1392                 }
1393         }
1394         while (len < pkt_len) {
1395                 write_size = pkt_len - len;
1396                 if (write_size > 24)
1397                         write_size = 24;
1398                 //printk("len=%d,write_size=%d,pkt_len=%d\n",len,write_size,pkt_len);
1399                 memset (CMVMSG, 0, sizeof (CMVMSG));
1400                 makeCMV (H2D_CMV_WRITE, INFO, 81, len / 2, (write_size + 1) / 2, (u16 *) (hdlc_pkt + len), CMVMSG);     //Write clear eoc message to ARC
1401                 ret = mei_ioctl ((struct inode *) 0, NULL,
1402                                  IFXMIPS_MEI_CMV_WINHOST,
1403                                  (unsigned long) CMVMSG);
1404                 if (ret != 0) {
1405                         return -EIO;
1406                 }
1407                 len += write_size;
1408         }
1409         makeCMV (H2D_CMV_WRITE, INFO, 83, 2, 1, &len, CMVMSG);  //Update tx message length
1410         ret = mei_ioctl ((struct inode *) 0, NULL, IFXMIPS_MEI_CMV_WINHOST,
1411                          (unsigned long) CMVMSG);
1412         if (ret != 0) {
1413                 return -EIO;
1414         }
1415
1416         data = (1 << 0);
1417         makeCMV (H2D_CMV_WRITE, CNTL, 2, 0, 1, &data, CMVMSG);  //Start to send
1418         ret = mei_ioctl ((struct inode *) 0, NULL, IFXMIPS_MEI_CMV_WINHOST,
1419                          (unsigned long) CMVMSG);
1420         if (ret != 0) {
1421                 return -EIO;
1422         }
1423         return 0;
1424 }
1425
1426 /**
1427  * Send hdlc packets
1428  * 
1429  * \param       hdlc_pkt        Pointer to hdlc packet
1430  * \param       hdlc_pkt_len    The number of bytes to send
1431  * \return      success or failure.
1432  * \ingroup     Internal
1433  */
1434 int
1435 ifx_me_hdlc_send (unsigned char *hdlc_pkt, int hdlc_pkt_len)
1436 {
1437         int hdlc_status = 0;
1438         u16 CMVMSG[MSG_LENGTH];
1439         int max_hdlc_tx_length = 0, ret = 0, retry = 0;
1440         int power_mode = 0;
1441         int send_busy_counter = 0;
1442         int send_retry = 0;
1443
1444       HDLC_SEND:
1445         // retry 1000 times (10 seconds)
1446         while (retry < 1000) {
1447                 /* In L2 power mode, do not read the OHC related parameters, 
1448                    instead give the indication to the calling IOCTL, 
1449                    that the readout fails (just return -EBUSY).  */
1450                 power_mode = get_l3_power_status();
1451                 if (power_mode == L2_POWER_MODE) {
1452                         return -EBUSY;
1453                 }
1454
1455                 hdlc_status = ifx_me_hdlc_status ();
1456                 if (ifx_me_is_resloved (hdlc_status) == ME_HDLC_RESOLVED)       // arc ready to send HDLC message
1457                 {
1458                         makeCMV (H2D_CMV_READ, INFO, 83, 0, 1, NULL, CMVMSG);   //Get Maximum Allowed HDLC Tx Message Length
1459                         ret = mei_ioctl ((struct inode *) 0, NULL,
1460                                          IFXMIPS_MEI_CMV_WINHOST,
1461                                          (unsigned long) CMVMSG);
1462                         if (ret != 0) {
1463                                 printk
1464                                         ("ifx_me_hdlc_send failed. Return -EIO");
1465                                 return -EIO;
1466                         }
1467                         max_hdlc_tx_length = CMVMSG[4];
1468                         ret = _ifx_me_hdlc_send (hdlc_pkt, hdlc_pkt_len,
1469                                                  max_hdlc_tx_length);
1470                         return ret;
1471                 }
1472                 else {
1473                         if (hdlc_status == ME_HDLC_MSG_SENT)
1474                                 send_busy_counter++;
1475                 }
1476                 retry++;
1477                 MEI_WAIT (1);
1478         }
1479         // wait 10 seconds and FW still report busy -> reset FW HDLC status
1480         if (send_busy_counter > 950 && send_retry == 0) {
1481                 u16 data = 0;
1482                 send_retry = 1;
1483                 retry = 0;
1484                 printk ("Reset FW HDLC status!!\n");
1485                 send_busy_counter = 0;
1486                 data = (1 << 1);
1487                 makeCMV (H2D_CMV_WRITE, CNTL, 2, 0, 1, NULL, CMVMSG);   //Force reset to idle
1488                 ret = mei_ioctl ((struct inode *) 0, NULL,
1489                                  IFXMIPS_MEI_CMV_WINHOST,
1490                                  (unsigned long) CMVMSG);
1491                 if (ret != 0) {
1492                         return -EIO;
1493                 }
1494                 goto HDLC_SEND;
1495         }
1496         printk ("ifx_me_hdlc_send failed. Return -EBUSY");
1497         return -EBUSY;
1498 }
1499
1500 /**
1501  * Read the hdlc packets
1502  * 
1503  * \param       hdlc_pkt        Pointer to hdlc packet
1504  * \param       hdlc_pkt_len    The maximum number of bytes to read
1505  * \return      The number of bytes which reads.
1506  * \ingroup     Internal
1507  */
1508 int
1509 ifx_mei_hdlc_read (char *hdlc_pkt, int max_hdlc_pkt_len)
1510 {
1511         u16 CMVMSG[MSG_LENGTH];
1512         int msg_read_len, ret = 0, pkt_len = 0, retry = 0;
1513
1514         while (retry < 10) {
1515                 ret = ifx_me_hdlc_status ();
1516                 if (ret == ME_HDLC_RESP_RCVD) {
1517                         int current_size = 0;
1518                         makeCMV (H2D_CMV_READ, INFO, 83, 3, 1, NULL, CMVMSG);   //Get EoC packet length
1519                         ret = mei_ioctl ((MEI_inode_t *) 0, NULL,
1520                                          IFXMIPS_MEI_CMV_WINHOST,
1521                                          (unsigned long) CMVMSG);
1522                         if (ret != 0) {
1523                                 return -EIO;
1524                         }
1525
1526                         pkt_len = CMVMSG[4];
1527                         if (pkt_len > max_hdlc_pkt_len) {
1528                                 ret = -ENOMEM;
1529                                 goto error;
1530                         }
1531                         while (current_size < pkt_len) {
1532                                 if (pkt_len - current_size >
1533                                     (MSG_LENGTH * 2 - 8))
1534                                         msg_read_len = (MSG_LENGTH * 2 - 8);
1535                                 else
1536                                         msg_read_len =
1537                                                 pkt_len - (current_size);
1538                                 makeCMV (H2D_CMV_READ, INFO, 82, 0 + (current_size / 2), (msg_read_len + 1) / 2, NULL, CMVMSG); //Get hdlc packet
1539                                 ret = mei_ioctl ((MEI_inode_t *) 0, NULL,
1540                                                  IFXMIPS_MEI_CMV_WINHOST,
1541                                                  (unsigned long) CMVMSG);
1542                                 if (ret != 0) {
1543                                         goto error;
1544                                 }
1545                                 memcpy (hdlc_pkt + current_size, &CMVMSG[4],
1546                                         msg_read_len);
1547                                 current_size += msg_read_len;
1548                         }
1549                         ret = current_size;
1550                         break;
1551                 }
1552                 else {
1553                         ret = -ENODATA;
1554                 }
1555
1556                 retry++;
1557
1558                 MEI_WAIT (10);
1559         }
1560       error:
1561         return ret;
1562 }
1563
1564 #if defined(IFXMIPS_CLEAR_EOC)
1565 int
1566 ifx_me_ceoc_send (struct sk_buff *eoc_pkt)
1567 {
1568         int ret, pkt_len = 0;
1569         unsigned char *pkt_data_ptr;
1570         int offset = 0;
1571         int swap_idx = 0;
1572
1573         if (adsl_mode <= 8 && adsl_mode_extend == 0)    // adsl mode
1574         {
1575                 pkt_len = eoc_pkt->len;
1576
1577                 pkt_data_ptr = kmalloc (pkt_len + 3, GFP_KERNEL);
1578
1579                 offset = 2;
1580                 pkt_data_ptr[0] = 0x4c;
1581                 pkt_data_ptr[1] = 0x81;
1582                 pkt_len += 2;
1583         } else {
1584                 pkt_len = eoc_pkt->len + 4;
1585                 pkt_data_ptr = kmalloc (pkt_len + 1 + 2, GFP_KERNEL);
1586                 memset (pkt_data_ptr, 0, pkt_len + 1 + 2);
1587                 //fill clear eoc header
1588                 pkt_data_ptr[0] = 0x1;
1589                 pkt_data_ptr[1] = 0x8;
1590                 pkt_data_ptr[2] = 0x4c;
1591                 pkt_data_ptr[3] = 0x81;
1592                 offset = 4;
1593         }
1594         for (swap_idx = 0; swap_idx < (eoc_pkt->len / 2) * 2; swap_idx += 2)
1595         {
1596                 //printk("%02X %02X ",eoc_pkt->data[swap_idx],eoc_pkt->data[swap_idx+1]);
1597                 pkt_data_ptr[swap_idx + offset] = eoc_pkt->data[swap_idx + 1];
1598                 pkt_data_ptr[swap_idx + 1 + offset] = eoc_pkt->data[swap_idx];
1599         }
1600         if (eoc_pkt->len % 2)
1601         {
1602                 //printk("%02X ",eoc_pkt->data[eoc_pkt->len-1]);
1603                 pkt_data_ptr[eoc_pkt->len - 1 + offset] =
1604                         eoc_pkt->data[eoc_pkt->len - 1];
1605                 pkt_data_ptr[eoc_pkt->len + offset] =
1606                         eoc_pkt->data[eoc_pkt->len - 1];
1607         }
1608         ret = ifx_me_hdlc_send (pkt_data_ptr, pkt_len);
1609
1610         if (pkt_data_ptr != eoc_pkt->data)
1611         {
1612                 kfree (pkt_data_ptr);
1613         }
1614         dev_kfree_skb (eoc_pkt);
1615         return ret;
1616 }
1617
1618 int
1619 get_me_ceoc_data (int pkt_len, int rx_buffer_addr, int rx_buffer_len,
1620                   u8 * data_ptr1)
1621 {
1622         int ret;
1623         MEI_ERROR dma_ret;
1624         u16 CMVMSG[MSG_LENGTH];
1625         int read_size, aread_size;
1626         int offset = 0;
1627         u8 *data = NULL, *data_ptr = NULL;
1628         int i, j;
1629         int over_read = 0;
1630
1631         i = j = 0;
1632
1633         read_size = (pkt_len / 4) + 4;
1634         offset = ceoc_read_idx % 4;
1635         over_read = read_size * 4 - pkt_len - offset;
1636
1637         ceoc_read_idx = (ceoc_read_idx & 0xFFFFFFFC);
1638
1639         data = kmalloc (read_size * 4, GFP_KERNEL);
1640         if (data == NULL)
1641                 goto error;
1642         data_ptr = kmalloc (read_size * 4, GFP_KERNEL);
1643         if (data_ptr == NULL)
1644                 goto error;
1645         if (ceoc_read_idx + read_size * 4 >= rx_buffer_len) {
1646                 aread_size = (rx_buffer_len - ceoc_read_idx) / 4;
1647         }
1648         else {
1649                 aread_size = read_size;
1650         }
1651
1652         //printk("aread_size = %d,ceoc_read_idx=%d,read_size=%d,offset=%d\n",aread_size,ceoc_read_idx,read_size,offset);
1653         dma_ret =
1654                 meiDebugRead (rx_buffer_addr + ceoc_read_idx, (u32 *) (data),
1655                               aread_size);
1656         ceoc_read_idx += aread_size * 4;
1657         if (aread_size != read_size) {
1658                 dma_ret =
1659                         meiDebugRead (rx_buffer_addr,
1660                                       (u32 *) (data) + aread_size,
1661                                       read_size - aread_size);
1662                 ceoc_read_idx = (read_size - aread_size) * 4;
1663         }
1664         if (ceoc_read_idx < over_read)
1665                 ceoc_read_idx = rx_buffer_len + ceoc_read_idx - over_read;
1666         else
1667                 ceoc_read_idx -= over_read;
1668
1669         if (offset == 0 || offset == 2) {
1670                 for (i = 0; i < read_size; i++) {
1671                         // 3412 --> 1234
1672
1673                         for (j = 0; j < 4; j++) {
1674                                 if (i * 4 + j - offset >= 0)
1675                                         data_ptr[i * 4 + j - offset] =
1676                                                 data[i * 4 + (3 - j)];
1677                         }
1678                 }
1679
1680         }
1681         else if (offset == 1) {
1682                 for (i = 0; i < pkt_len; i = i + 4) {
1683
1684                         data_ptr[i + 1] = data[i + 1];
1685                         data_ptr[i] = data[i + 2];
1686                         data_ptr[i + 3] = data[i + 7];
1687                         data_ptr[i + 2] = data[i];
1688                 }
1689         }
1690         else if (offset == 3) {
1691                 for (i = 0; i < pkt_len; i = i + 4) {
1692                         data_ptr[i + 1] = data[i + 7];
1693                         data_ptr[i + 0] = data[i];
1694                         data_ptr[i + 3] = data[i + 5];
1695                         data_ptr[i + 2] = data[i + 6];
1696                 }
1697         }
1698         if (pkt_len % 2 == 1)
1699                 data_ptr[pkt_len - 1] = data_ptr[pkt_len];
1700
1701         kfree (data);
1702         memcpy (data_ptr1, data_ptr, pkt_len);
1703         kfree (data_ptr);
1704
1705         makeCMV (H2D_CMV_WRITE, INFO, 85, 3, 1, &ceoc_read_idx, CMVMSG);
1706         ret = mei_ioctl ((struct inode *) 0, NULL, IFXMIPS_MEI_CMV_WINHOST,
1707                          (unsigned long) CMVMSG);
1708         if (ret != 0) {
1709                 goto error;
1710         }
1711
1712         return dma_ret;
1713       error:
1714         kfree (data);
1715         kfree (data_ptr);
1716         return -1;
1717 }
1718
1719 int
1720 ifx_me_ceoc_receive (int ceoc_write_idx, int rx_buffer_len,
1721                      struct sk_buff **eoc_pkt)
1722 {
1723         u16 CMVMSG[MSG_LENGTH];
1724         int pkt_len, ret;
1725         u16 lsw_addr, msw_addr;
1726         u32 rx_buffer_addr = 0;
1727         MEI_ERROR dma_ret;
1728
1729         //printk("rx_buffer_len=%d,ceoc_read_idx=%d,ceoc_write_idx=%d\n",rx_buffer_len,ceoc_read_idx,ceoc_write_idx);
1730         if (ceoc_write_idx > ceoc_read_idx) {
1731                 pkt_len = ceoc_write_idx - ceoc_read_idx;
1732         }
1733         else {
1734                 pkt_len = rx_buffer_len - ceoc_read_idx + ceoc_write_idx;
1735         }
1736         *eoc_pkt = dev_alloc_skb (pkt_len);
1737         if (*eoc_pkt == NULL) {
1738                 printk ("Out of memory!\n");
1739                 ret = -ENOMEM;
1740                 goto error;
1741         }
1742
1743         makeCMV (H2D_CMV_READ, INFO, 85, 0, 1, NULL, CMVMSG);   //Get HDLC packet 
1744         ret = mei_ioctl ((struct inode *) 0, NULL, IFXMIPS_MEI_CMV_WINHOST,
1745                          (unsigned long) CMVMSG);
1746         if (ret != 0) {
1747                 goto error;
1748         }
1749         lsw_addr = CMVMSG[4];
1750
1751         makeCMV (H2D_CMV_READ, INFO, 85, 1, 1, NULL, CMVMSG);   //Get HDLC packet 
1752         ret = mei_ioctl ((struct inode *) 0, NULL, IFXMIPS_MEI_CMV_WINHOST,
1753                          (unsigned long) CMVMSG);
1754         if (ret != 0) {
1755                 goto error;
1756         }
1757         msw_addr = CMVMSG[4];
1758         rx_buffer_addr = msw_addr << 16 | lsw_addr;
1759         dma_ret =
1760                 get_me_ceoc_data (pkt_len, rx_buffer_addr, rx_buffer_len,
1761                                   (u16 *) skb_put (*eoc_pkt, pkt_len));
1762         if (dma_ret != MEI_SUCCESS) {
1763                 ret = -EIO;
1764                 goto error;
1765         }
1766
1767         return 0;
1768       error:
1769         if (*eoc_pkt != NULL)
1770                 dev_kfree_skb (*eoc_pkt);
1771         return ret;
1772 }
1773
1774 int
1775 ifx_mei_ceoc_rx (void)
1776 {
1777         u16 CMVMSG[MSG_LENGTH];
1778         int rx_buffer_len, ret, pkt_len = 0;
1779         struct sk_buff *eoc_pkt;
1780         u16 ceoc_write_idx = 0;
1781
1782         makeCMV (H2D_CMV_READ, INFO, 85, 2, 1, NULL, CMVMSG);   //Get EoC packet length
1783         ret = mei_ioctl ((struct inode *) 0, NULL, IFXMIPS_MEI_CMV_WINHOST,
1784                          (unsigned long) CMVMSG);
1785         if (ret != 0) {
1786                 printk ("ioctl fail!!\n");
1787         }
1788         rx_buffer_len = CMVMSG[4];
1789
1790         makeCMV (H2D_CMV_READ, INFO, 85, 4, 1, NULL, CMVMSG);   //Get write index
1791         ret = mei_ioctl ((struct inode *) 0, NULL, IFXMIPS_MEI_CMV_WINHOST,
1792                          (unsigned long) CMVMSG);
1793         if (ret != 0) {
1794                 return -EIO;
1795         }
1796
1797         ceoc_write_idx = CMVMSG[4];
1798         ret = ifx_me_ceoc_receive (ceoc_write_idx, rx_buffer_len, &eoc_pkt);
1799 #if defined (CONFIG_ATM_IFXMIPS)
1800         if (ret == 0) {
1801                 skb_pull (eoc_pkt, 2);  // skip 4c 81 header
1802                 ifx_push_ceoc (eoc_pkt);        //pass data to higher layer
1803         }
1804
1805         return ret;
1806 #endif
1807 }
1808
1809 static int
1810 adsl_clear_eoc_poll (void *unused)
1811 {
1812         struct task_struct *tsk = current;
1813
1814         daemonize("mei_eoc_poll");
1815         strcpy(tsk->comm, "mei_ceoc_poll");
1816         sigfillset(&tsk->blocked);
1817
1818         while (1)
1819         {
1820                 MEI_WAIT_EVENT (wait_queue_hdlc_poll);
1821                 if (showtime)
1822                         ifx_mei_ceoc_rx();
1823                 }
1824         return 0;
1825 }
1826 #endif //#if defined(IFXMIPS_CLEAR_EOC)
1827
1828 #ifdef IFXMIPS_CLEAR_EOC
1829 static int
1830 ifxmips_mei_ceoc_init (void)
1831 {
1832         kernel_thread (adsl_clear_eoc_poll, NULL,
1833                        CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
1834         return 0;
1835 }
1836 #endif
1837
1838 //////////////////////  Driver Structure        ///////////////////////
1839
1840 /**
1841  * Free the memory for ARC firmware
1842  * 
1843  * \param       type    Free all memory or free the unused memory after showtime
1844  * \ingroup     Internal
1845  */
1846 static int
1847 free_image_buffer (int type)
1848 {
1849         int idx = 0;
1850         for (idx = 0; idx < MAX_BAR_REGISTERS; idx++) {
1851                 printk ("meminfo[%d].type=%d,size=%ld,addr=%X\n", idx,
1852                                  adsl_mem_info[idx].type, adsl_mem_info[idx].size,
1853                                  (unsigned int)adsl_mem_info[idx].address);
1854                 if (type == FREE_ALL || adsl_mem_info[idx].type == type) {
1855                         if (adsl_mem_info[idx].size > 0) {
1856                                 kfree (adsl_mem_info[idx].org_address);
1857                                 adsl_mem_info[idx].address = 0;
1858                                 adsl_mem_info[idx].size = 0;
1859                                 adsl_mem_info[idx].type = 0;
1860                                 adsl_mem_info[idx].nCopy = 0;
1861                         }
1862                 }
1863         }
1864         return 0;
1865 }
1866
1867 /**
1868  * Allocate memory for ARC firmware
1869  * 
1870  * \param       size            The number of bytes to allocate.
1871  * \param       adsl_mem_info   Pointer to firmware information.
1872  * \ingroup     Internal
1873  */
1874 static int
1875 alloc_processor_memory (unsigned long size, smmu_mem_info_t * adsl_mem_info)
1876 {
1877         char *mem_ptr = NULL;
1878         char *org_mem_ptr = NULL;
1879         int idx = 0;
1880         long total_size = 0;
1881         long img_size = size;
1882         int err = 0;
1883
1884         // Alloc Swap Pages
1885         while (img_size > 0 && idx < MAX_BAR_REGISTERS) {
1886                 // skip bar15 for XDATA usage.
1887 #ifndef DFE_LOOPBACK
1888                 if (idx == XDATA_REGISTER)
1889                         idx++;
1890 #endif
1891                 if (idx == MAX_BAR_REGISTERS - 1)
1892                 {
1893                         //allocate 1MB memory for bar16
1894                         org_mem_ptr = kmalloc (1024 * 1024, GFP_ATOMIC);
1895                         mem_ptr = (char*)((unsigned long) (org_mem_ptr +  1023) & 0xFFFFFC00);
1896                         adsl_mem_info[idx].size = 1024 * 1024;
1897                 } else {
1898                         org_mem_ptr = kmalloc (SDRAM_SEGMENT_SIZE, GFP_ATOMIC);
1899                         mem_ptr = (char*)((unsigned long) (org_mem_ptr + 1023) & 0xFFFFFC00);
1900                         adsl_mem_info[idx].size = SDRAM_SEGMENT_SIZE;
1901                 }
1902                 if (org_mem_ptr == NULL)
1903                 {
1904                         printk ("kmalloc memory fail!\n");
1905                         err = -ENOMEM;
1906                         goto allocate_error;
1907                 }
1908                 adsl_mem_info[idx].address = mem_ptr;
1909                 adsl_mem_info[idx].org_address = org_mem_ptr;
1910
1911                 img_size -= SDRAM_SEGMENT_SIZE;
1912                 total_size += SDRAM_SEGMENT_SIZE;
1913                 printk("alloc memory idx=%d,img_size=%ld,addr=%X\n",
1914                                 idx, img_size, (unsigned int)adsl_mem_info[idx].address);
1915                 idx++;
1916         }
1917         if (img_size > 0)
1918         {
1919                 printk ("Image size is too large!\n");
1920                 err = -EFBIG;
1921                 goto allocate_error;
1922         }
1923         err = idx;
1924         return err;
1925
1926       allocate_error:
1927         free_image_buffer (FREE_ALL);
1928         return err;
1929 }
1930
1931 /**
1932  * Program the BAR registers
1933  * 
1934  * \param       nTotalBar       The number of bar to program.
1935  * \ingroup     Internal
1936  */
1937 static int
1938 update_bar_register (int nTotalBar)
1939 {
1940         int idx = 0;
1941
1942         for (idx = 0; idx < nTotalBar; idx++) {
1943                 //skip XDATA register
1944                 if (idx == XDATA_REGISTER)
1945                         idx++;
1946                 meiLongwordWrite ( MEI_XMEM_BAR_BASE + idx * 4,
1947                                   (((uint32_t) adsl_mem_info[idx].
1948                                     address) & 0x0FFFFFFF));
1949                 printk ("BAR%d=%08X, addr=%08X\n", idx,
1950                                  (((uint32_t) adsl_mem_info[idx].
1951                                    address) & 0x0FFFFFFF),
1952                                  (((uint32_t) adsl_mem_info[idx].address)));
1953         }
1954         for (idx = nTotalBar; idx < MAX_BAR_REGISTERS; idx++) {
1955                 if (idx == XDATA_REGISTER)
1956                         idx++;
1957                 meiLongwordWrite ( MEI_XMEM_BAR_BASE + idx * 4,
1958                                   (((uint32_t) adsl_mem_info[nTotalBar - 1].
1959                                     address) & 0x0FFFFFFF));
1960         }
1961
1962         meiLongwordWrite (MEI_XMEM_BAR_BASE + XDATA_REGISTER * 4,
1963                           (((uint32_t) adsl_mem_info[XDATA_REGISTER].
1964                             address) & 0x0FFFFFFF));
1965         // update MEI_XDATA_BASE_SH
1966         printk ("update bar15 register with %08lX\n",
1967                          ((unsigned long) adsl_mem_info[XDATA_REGISTER].
1968                           address) & 0x0FFFFFFF);
1969         meiLongwordWrite (MEI_XDATA_BASE_SH,
1970                           ((unsigned long) adsl_mem_info[XDATA_REGISTER].
1971                            address) & 0x0FFFFFFF);
1972         return MEI_SUCCESS;
1973 }
1974
1975 /**
1976  * Copy the firmware to BARs memory.
1977  * 
1978  * \param       filp            Pointer to the file structure.
1979  * \param       buf             Pointer to the data.
1980  * \param       size            The number of bytes to copy.
1981  * \param       loff            The file offset.
1982  * \return      The current file position.
1983  * \ingroup     Internal
1984  */
1985 ssize_t
1986 mei_write (MEI_file_t * filp, char *buf, size_t size, loff_t * loff)
1987 {
1988         ARC_IMG_HDR img_hdr_tmp, *img_hdr;
1989
1990         size_t nRead = 0, nCopy = 0;
1991         char *mem_ptr;
1992         ssize_t retval = -ENOMEM;
1993         int idx = 0;
1994
1995         if (*loff == 0) {
1996                 if (size < sizeof (img_hdr)) {
1997                         printk ("Firmware size is too small!\n");
1998                         return retval;
1999                 }
2000                 copy_from_user ((char *) &img_hdr_tmp, buf,
2001                                 sizeof (img_hdr_tmp));
2002                 image_size = le32_to_cpu (img_hdr_tmp.size) + 8;        // header of image_size and crc are not included.
2003                 if (image_size > 1024 * 1024) {
2004                         printk ("Firmware size is too large!\n");
2005                         return retval;
2006                 }
2007                 // check if arc is halt
2008                 if (arc_halt_flag != 1) {
2009                         meiResetARC ();
2010                         meiHaltArc ();
2011                 }
2012
2013                 // reset part of PPE 
2014                 *(unsigned long *) (IFXMIPS_PPE32_SRST) = 0xC30;
2015                 *(unsigned long *) (IFXMIPS_PPE32_SRST) = 0xFFF;
2016
2017                 free_image_buffer (FREE_ALL);   //free all
2018
2019                 retval = alloc_processor_memory (image_size, adsl_mem_info);
2020                 if (retval < 0) {
2021                         printk ("Error: No memory space left.\n");
2022                         goto error;
2023                 }
2024
2025                 for (idx = 0; idx < retval; idx++) {
2026                         //skip XDATA register
2027                         if (idx == XDATA_REGISTER)
2028                                 idx++;
2029                         if (idx * SDRAM_SEGMENT_SIZE <
2030                             le32_to_cpu (img_hdr_tmp.page[0].p_offset)) {
2031                                 adsl_mem_info[idx].type = FREE_RELOAD;
2032                         }
2033                         else {
2034                                 adsl_mem_info[idx].type = FREE_SHOWTIME;
2035                         }
2036
2037                 }
2038                 nBar = retval;
2039
2040                 img_hdr = (ARC_IMG_HDR *) adsl_mem_info[0].address;
2041
2042 #if !defined(__LINUX__)
2043                 adsl_mem_info[XDATA_REGISTER].org_address =
2044                         kmalloc (SDRAM_SEGMENT_SIZE + 1023, GFP_ATOMIC);
2045 #else
2046                 adsl_mem_info[XDATA_REGISTER].org_address =
2047                         kmalloc (SDRAM_SEGMENT_SIZE, GFP_ATOMIC);
2048 #endif
2049                 adsl_mem_info[XDATA_REGISTER].address =
2050                         (char
2051                          *) ((unsigned long) (adsl_mem_info[XDATA_REGISTER].
2052                                               org_address +
2053                                               1023) & 0xFFFFFC00);
2054                 adsl_mem_info[XDATA_REGISTER].size = SDRAM_SEGMENT_SIZE;
2055                 if (adsl_mem_info[XDATA_REGISTER].address == NULL) {
2056                         printk ("kmalloc memory fail!\n");
2057                         retval = -ENOMEM;
2058                         goto error;
2059                 }
2060                 adsl_mem_info[XDATA_REGISTER].type = FREE_RELOAD;
2061                 update_bar_register (nBar);
2062
2063         }
2064         else if (image_size == 0) {
2065                 printk ("Error: Firmware size=0! \n");
2066                 goto error;
2067         }
2068         else {
2069                 if (arc_halt_flag == 0) {
2070                         printk
2071                                 ("Please download the firmware from the beginning of the firmware!\n");
2072                         goto error;
2073                 }
2074         }
2075
2076         nRead = 0;
2077         while (nRead < size) {
2078                 long offset = ((long) (*loff) + nRead) % SDRAM_SEGMENT_SIZE;
2079                 idx = (((long) (*loff)) + nRead) / SDRAM_SEGMENT_SIZE;
2080                 mem_ptr = (char *)
2081                         KSEG1ADDR ((unsigned long) (adsl_mem_info[idx].
2082                                                     address) + offset);
2083                 if ((size - nRead + offset) > SDRAM_SEGMENT_SIZE)
2084                         nCopy = SDRAM_SEGMENT_SIZE - offset;
2085                 else
2086                         nCopy = size - nRead;
2087                 copy_from_user (mem_ptr, buf + nRead, nCopy);
2088 #ifdef IMAGE_SWAP
2089                 for (offset = 0; offset < (nCopy / 4); offset++) {
2090                         ((unsigned long *) mem_ptr)[offset] =
2091                                 le32_to_cpu (((unsigned long *)
2092                                               mem_ptr)[offset]);
2093                 }
2094 #endif //IMAGE_SWAP
2095                 nRead += nCopy;
2096                 adsl_mem_info[idx].nCopy += nCopy;
2097         }
2098
2099 #if     ( defined(HEADER_SWAP) && !defined(IMAGE_SWAP)) || (defined(IMAGE_SWAP) && !defined(HEADER_SWAP))
2100         if (*loff == 0) {
2101
2102                 for (idx = 0;
2103                      idx <
2104                      (sizeof (ARC_IMG_HDR) +
2105                       (le32_to_cpu (img_hdr_tmp.count) -
2106                        1) * sizeof (ARC_SWP_PAGE_HDR)) / 4; idx++) {
2107                         ((unsigned long *) img_hdr)[idx] =
2108                                 le32_to_cpu (((unsigned long *)
2109                                               img_hdr)[idx]);
2110                 }
2111         }
2112 #endif //( defined(HEADER_SWAP) && !defined(IMAGE_SWAP)) || (defined(IMAGE_SWAP) && !defined(HEADER_SWAP))
2113         printk ("size=%X,loff=%08X\n", size, (unsigned int) *loff);
2114
2115         *loff += size;
2116         return size;
2117       error:
2118         free_image_buffer (FREE_ALL);
2119
2120         return retval;
2121 }
2122
2123 /********************************************************
2124  * L3 Power Mode                                        *
2125  ********************************************************/
2126 /**
2127  * Send a CMV message.
2128  * This function sends a CMV message to ARC
2129  * 
2130  * \param       opcode          The message opcode
2131  * \param       group           The message group number
2132  * \param       address         The message address.
2133  * \param       index           The message index.
2134  * \param       size            The number of words to read/write.
2135  * \param       data            The pointer to data.
2136  * \param       CMVMSG          The pointer to message buffer.
2137  * \return      0: success 
2138  * \ingroup     Internal
2139  */
2140 int
2141 send_cmv (u8 opcode, u8 group, u16 address, u16 index, int size, u16 * data, u16 * CMVMSG)
2142 {
2143         int ret;
2144
2145         makeCMV(opcode, group, address, index, size, data, CMVMSG);
2146         ret = mei_ioctl((struct inode *) 0, NULL, IFXMIPS_MEI_CMV_WINHOST, (unsigned long)CMVMSG);
2147         return ret;
2148 }
2149
2150 #ifdef IFX_ADSL_L3_MODE_SUPPORT
2151
2152 /**
2153  * Check the L3 request from CO
2154  * This function Check if CPE received the L3 request from CO
2155  * \return      1: got L3 request.  
2156  * \ingroup     Internal
2157  */
2158 int
2159 check_co_l3_shutdown_request (void)
2160 {
2161         u16 CMVMSG[MSG_LENGTH];
2162         if (modem_ready == 1) {
2163                 if (send_cmv (H2D_CMV_READ, STAT, 4, 0, 1, NULL, CMVMSG) != 0) {
2164                         return -EBUSY;
2165                 }
2166                 if (CMVMSG[4] & BIT14) {
2167                         return 1;
2168                 }
2169         }
2170         return 0;
2171 }
2172
2173 /**
2174  * Check the L3 status
2175  * This function get the CPE Power Management Mode status
2176  * \return      0: L0 Mode
2177  *              2: L2 Mode
2178  *              3: L3 Mode
2179  * \ingroup     Internal
2180  */
2181 int
2182 get_l3_power_status (void)
2183 {
2184         u16 CMVMSG[MSG_LENGTH];
2185         if (modem_ready == 0) {
2186                 return L3_POWER_MODE;
2187         }
2188         else {
2189                 if (send_cmv (H2D_CMV_READ, STAT, 18, 0, 1, NULL, CMVMSG) !=
2190                     0) {
2191                         return -EBUSY;
2192                 }
2193                 return ((int) CMVMSG[4]);
2194
2195         }
2196         return 0;
2197 }
2198
2199 /**
2200  * Send a L3 request to CO
2201  * This function send a L3 request to CO and check the CO response.
2202  * \return      0: Success. Others: Fail.
2203  * \ingroup     Internal
2204  */
2205 int
2206 send_l3_shutdown_cmd (void)
2207 {
2208         u16 cmd = 0x1;
2209         int nRetry = 0;
2210         u16 CMVMSG[MSG_LENGTH];
2211
2212         if (modem_ready == 0) {
2213                 return -EBUSY;
2214         }
2215         // send l3 request to CO
2216         if (send_cmv (H2D_CMV_WRITE, CNTL, 3, 0, 1, &cmd, CMVMSG) != 0) {
2217                 return -EBUSY;
2218         }
2219       retry:
2220         MEI_WAIT (10);
2221
2222         // check CO response
2223         if (send_cmv (H2D_CMV_READ, STAT, 20, 0, 1, NULL, CMVMSG) != 0) {
2224                 return -EBUSY;
2225         }
2226         if (CMVMSG[4] == 0) {
2227                 nRetry++;
2228                 if (nRetry < 10) {
2229                         goto retry;
2230                 }
2231                 else {
2232                         return -EBUSY;
2233                 }
2234
2235         }
2236         else if (CMVMSG[4] == 1)        // reject
2237         {
2238                 return -EPERM;
2239         }
2240         else if (CMVMSG[4] == 2)        // ok
2241         {
2242                 return 0;
2243         }
2244         else if (CMVMSG[4] == 3)        // failure
2245         {
2246                 return -EAGAIN;
2247         }
2248         return 0;
2249 }
2250
2251 /**
2252  * Enable L3 Power Mode
2253  * This function send a L3 request to CO and check the CO response. Then reboot the CPE to enter L3 Mode.
2254  * \return      0: Success. Others: Fail.
2255  * \ingroup     Internal
2256  */
2257 int
2258 set_l3_shutdown (void)
2259 {
2260         int ret = 0;
2261         if (l3_shutdown == 0) {
2262                 // send l3 request to CO
2263                 ret = send_l3_shutdown_cmd ();
2264                 if (ret == 0)   //got CO ACK
2265                 {
2266                         //reboot adsl and block autoboot daemon
2267                         ret = mei_ioctl ((struct inode *) 0, NULL, IFXMIPS_MEI_REBOOT, (unsigned long)NULL);
2268                         l3_shutdown = 1;
2269                 }
2270         }
2271         return ret;
2272 }
2273
2274 /**
2275  * Disable L3 Power Mode
2276  * This function disable L3 Mode and wake up the autoboot daemon.
2277  * \return      0: Success.
2278  * \ingroup     Internal
2279  */
2280 //l3 power mode disable
2281 int
2282 set_l3_power_on (void)
2283 {
2284         if (l3_shutdown == 1) {
2285                 l3_shutdown = 0;
2286                 // wakeup autoboot daemon
2287                 MEI_WAKEUP_EVENT (wait_queue_l3);
2288
2289         }
2290         return 0;
2291 }
2292
2293 /********************************************************
2294  * End of L3 Power Mode                                 *
2295  ********************************************************/
2296 #endif //IFX_ADSL_L3_MODE_SUPPORT
2297
2298 #ifdef CONFIG_IFXMIPS_MEI_LED
2299 /*
2300  *  LED Initialization function
2301  */
2302 int
2303 meiADSLLedInit (void)
2304 {
2305         u16 data = 0x0600;
2306         u16 CMVMSG[MSG_LENGTH];
2307
2308         data = 0x0400;
2309 #if defined(DATA_LED_SUPPORT) && defined (DATA_LED_ADSL_FW_HANDLE)
2310         data |= 0x200;
2311 #endif
2312         // Setup ADSL Link/Data LED
2313         if (send_cmv (H2D_CMV_WRITE, INFO, 91, 0, 1, &data, CMVMSG) != 0) {
2314                 return -EBUSY;
2315         }
2316
2317         if (send_cmv (H2D_CMV_WRITE, INFO, 91, 2, 1, &data, CMVMSG) != 0) {
2318                 return -EBUSY;
2319         }
2320
2321         // Let FW to handle ADSL Link LED
2322         data = 0x0a03;          //invert the LED signal as per input from Stefan on 13/11/2006
2323         if (send_cmv (H2D_CMV_WRITE, INFO, 91, 4, 1, &data, CMVMSG) != 0) {
2324                 return -EBUSY;
2325         }
2326
2327 #ifdef DATA_LED_SUPPORT
2328 #ifdef DATA_LED_ADSL_FW_HANDLE
2329
2330         // Turn ADSL Data LED on
2331         data = 0x0900;
2332         if (send_cmv (H2D_CMV_WRITE, INFO, 91, 5, 1, &data, CMVMSG) != 0) {
2333                 return -EBUSY;
2334         }
2335 #else
2336         ifxmips_led_set(0x1);
2337 #endif
2338 #endif
2339         return 0;
2340 }
2341 #endif
2342
2343 #ifdef IFX_ADSL_DUAL_LATENCY_SUPPORT
2344 /* 
2345  * Dual Latency Path Initialization function
2346  */
2347 int
2348 meiDualLatencyInit (void)
2349 {
2350         u16 nDual = 0;
2351         u16 CMVMSG[MSG_LENGTH];
2352
2353         // setup up stream path 
2354         if (bDualLatency & DUAL_LATENCY_US_ENABLE) {
2355                 nDual = 2;
2356         }
2357         else {
2358                 nDual = 1;
2359         }
2360
2361         if (send_cmv (H2D_CMV_WRITE, CNFG, 10, 0, 1, &nDual, CMVMSG) != 0) {
2362                 return -EBUSY;
2363         }
2364
2365         if (send_cmv (H2D_CMV_WRITE, CNFG, 11, 0, 1, &nDual, CMVMSG) != 0) {
2366                 return -EBUSY;
2367         }
2368
2369         // setup down stream path       
2370         if (bDualLatency & DUAL_LATENCY_DS_ENABLE) {
2371                 nDual = 2;
2372         }
2373         else {
2374                 nDual = 1;
2375         }
2376
2377         if (send_cmv (H2D_CMV_WRITE, CNFG, 21, 0, 1, &nDual, CMVMSG) != 0) {
2378                 return -EBUSY;
2379         }
2380         if (send_cmv (H2D_CMV_WRITE, CNFG, 22, 0, 1, &nDual, CMVMSG) != 0) {
2381                 return -EBUSY;
2382         }
2383         return 0;
2384 }
2385
2386 int
2387 mei_is_dual_latency_enabled (void)
2388 {
2389         return bDualLatency;
2390 }
2391 #endif
2392
2393 int
2394 meiAdslStartupInit (void)
2395 {
2396 #ifdef CONFIG_IFXMIPS_MEI_LED
2397         meiADSLLedInit ();
2398 #endif
2399 #ifdef IFX_ADSL_DUAL_LATENCY_SUPPORT
2400         meiDualLatencyInit ();
2401 #endif
2402         return 0;
2403 }
2404
2405 /**
2406  * MEI IO controls for user space accessing
2407  * 
2408  * \param       ino             Pointer to the stucture of inode.
2409  * \param       fil             Pointer to the stucture of file.
2410  * \param       command         The ioctl command.
2411  * \param       lon             The address of data.
2412  * \return      Success or failure.
2413  * \ingroup     Internal
2414  */
2415 int
2416 mei_ioctl (MEI_inode_t * ino, MEI_file_t * fil, unsigned int command,
2417            unsigned long lon)
2418 {
2419         int i;
2420
2421         int meierr = MEI_SUCCESS;
2422         meireg regrdwr;
2423         meidebug debugrdwr;
2424         u32 arc_debug_data, reg_data;
2425 #ifdef IFXMIPS_CLEAR_EOC
2426         u16 data;
2427         struct sk_buff *eoc_skb;
2428 #endif //IFXMIPS_CLEAR_EOC
2429         u16 RxMessage[MSG_LENGTH] __attribute__ ((aligned (4)));
2430         u16 TxMessage[MSG_LENGTH] __attribute__ ((aligned (4)));
2431
2432         int from_kernel = 0;    //joelin
2433         if (ino == (MEI_inode_t *) 0)
2434                 from_kernel = 1;        //joelin
2435         if (command < IFXMIPS_MEI_START) {
2436 #ifdef CONFIG_IFXMIPS_MEI_MIB
2437                 return mei_mib_ioctl (ino, fil, command, lon);
2438 #endif //CONFIG_IFXMIPS_MEI_MIB
2439
2440                 if (command == IFXMIPS_MIB_LO_ATUR
2441                     || command == IFXMIPS_MIB_LO_ATUC)
2442                         return MEI_SUCCESS;
2443                 printk
2444                         ("No such ioctl command (0x%X)! MEI ADSL MIB is not supported!\n",
2445                          command);
2446                 return -ENOIOCTLCMD;
2447         }
2448         else {
2449                 switch (command) {
2450                 case IFXMIPS_MEI_START:
2451
2452                         showtime = 0;
2453                         loop_diagnostics_completed = 0;
2454                         if (time_disconnect.tv_sec == 0)
2455                                 do_gettimeofday (&time_disconnect);
2456
2457                         if (MEI_MUTEX_LOCK (mei_sema))  //disable CMV access until ARC ready
2458                         {
2459                                 printk ("-ERESTARTSYS\n");
2460                                 return -ERESTARTSYS;
2461                         }
2462
2463                         meiMailboxInterruptsDisable (); //disable all MEI interrupts
2464                         if (mei_arc_swap_buff == NULL) {
2465                                 mei_arc_swap_buff =
2466                                         (u32 *) kmalloc (MAXSWAPSIZE * 4,
2467                                                          GFP_KERNEL);
2468                                 if (mei_arc_swap_buff == NULL) {
2469                                         printk
2470                                                 ("\n\n malloc fail for codeswap buff");
2471                                         meierr = MEI_FAILURE;
2472                                 }
2473                         }
2474                         if (meiRunAdslModem () != MEI_SUCCESS) {
2475                                 printk
2476                                         ("meiRunAdslModem()  error...");
2477                                 meierr = MEI_FAILURE;
2478                         }
2479 #ifdef IFX_ADSL_L3_MODE_SUPPORT
2480                         /* L3 Power Mode Start */
2481                         if (l3_shutdown == 1) {
2482                                 // block autoboot daemon until l3 power mode disable
2483                                 MEI_WAIT_EVENT (wait_queue_l3);
2484                         }
2485                         /* L3 Power Mode End */
2486 #endif //IFX_ADSL_L3_MODE_SUPPORT
2487                         if (autoboot_enable_flag)
2488                                 meiAdslStartupInit ();
2489                         break;
2490
2491                 case IFXMIPS_MEI_SHOWTIME:
2492                         if (MEI_MUTEX_LOCK (mei_sema))
2493                                 return -ERESTARTSYS;
2494
2495                         do_gettimeofday (&time_showtime);
2496                         unavailable_seconds +=
2497                                 time_showtime.tv_sec - time_disconnect.tv_sec;
2498                         time_disconnect.tv_sec = 0;
2499                         makeCMV (H2D_CMV_READ, RATE, 0, 0, 4, NULL, TxMessage); //maximum allowed tx message length, in bytes
2500                         if (meiCMV (TxMessage, YES_REPLY, RxMessage) !=
2501                             MEI_SUCCESS) {
2502                                 printk
2503                                         ("\n\nCMV fail, Group RAGE Address 0 Index 0");
2504                         }
2505                         else {
2506                                 u32 rate_fast;
2507                                 u32 rate_intl;
2508                                 rate_intl = RxMessage[4] | RxMessage[5] << 16;
2509                                 rate_fast = RxMessage[6] | RxMessage[7] << 16;
2510                                 // 609251:tc.chen Fix ATM QoS issue start
2511                                 if (rate_intl && rate_fast)     // apply cell rate to each path
2512                                 {
2513 #ifdef CONFIG_ATM_IFXMIPS
2514                                         ifx_atm_set_cell_rate (1,
2515                                                                rate_intl /
2516                                                                (53 * 8));
2517                                         ifx_atm_set_cell_rate (0,
2518                                                                rate_fast /
2519                                                                (53 * 8));
2520 #endif
2521                                 }
2522                                 else if (rate_fast)     // apply fast path cell rate to atm interface 0
2523                                 {
2524 #ifdef CONFIG_ATM_IFXMIPS
2525                                         ifx_atm_set_cell_rate (0,
2526                                                                rate_fast /
2527                                                                (53 * 8));
2528 #endif
2529                                 }
2530                                 else if (rate_intl)     // apply interleave path cell rate to atm interface 0
2531                                 {
2532 #ifdef CONFIG_ATM_IFXMIPS
2533                                         ifx_atm_set_cell_rate (0,
2534                                                                rate_intl /
2535                                                                (53 * 8));
2536 #endif
2537                                 }
2538                                 else {
2539                                         printk ("Got rate fail.\n");
2540                                 }
2541                                 // 609251:tc.chen end 
2542                         }
2543
2544 #ifdef IFXMIPS_CLEAR_EOC
2545                         data = 1;
2546                         makeCMV (H2D_CMV_WRITE, OPTN, 24, 0, 1, &data,
2547                                  TxMessage);
2548                         if (meiCMV (TxMessage, YES_REPLY, RxMessage) !=
2549                             MEI_SUCCESS) {
2550                                 printk ("Enable clear eoc fail!\n");
2551                         }
2552 #endif
2553                         // read adsl mode
2554                         makeCMV (H2D_CMV_READ, STAT, 1, 0, 1, NULL,
2555                                  TxMessage);
2556                         if (meiCMV (TxMessage, YES_REPLY, RxMessage) !=
2557                             MEI_SUCCESS) {
2558 #ifdef IFXMIPS_MEI_DEBUG_ON
2559                                 printk ("\n\nCMV fail, Group STAT Address 1 Index 0");
2560 #endif
2561                         }
2562                         adsl_mode = RxMessage[4];
2563                         makeCMV (H2D_CMV_READ, STAT, 17, 0, 1, NULL,
2564                                  TxMessage);
2565                         if (meiCMV (TxMessage, YES_REPLY, RxMessage) !=
2566                             MEI_SUCCESS) {
2567 #ifdef IFXMIPS_MEI_DEBUG_ON
2568                                 printk ("\n\nCMV fail, Group STAT Address 1 Index 0");
2569 #endif
2570                         }
2571                         adsl_mode_extend = RxMessage[4];
2572 #ifdef CONFIG_IFXMIPS_MEI_MIB
2573                         mei_mib_adsl_link_up ();
2574 #endif
2575
2576 //joelin 04/16/2005-start
2577                         makeCMV (H2D_CMV_WRITE, PLAM, 10, 0, 1,
2578                                  &unavailable_seconds, TxMessage);
2579                         if (meiCMV (TxMessage, YES_REPLY, RxMessage) !=
2580                             MEI_SUCCESS) {
2581                                 printk
2582                                         ("\n\nCMV fail, Group 7 Address 10 Index 0");
2583                         }
2584
2585 //joelin 04/16/2005-end         
2586                         showtime = 1;
2587                         free_image_buffer (FREE_SHOWTIME);
2588                         MEI_MUTEX_UNLOCK (mei_sema);
2589                         break;
2590
2591                 case IFXMIPS_MEI_HALT:
2592                         if (arc_halt_flag == 0) {
2593                                 meiResetARC ();
2594                                 meiHaltArc ();
2595                         }
2596                         break;
2597                 case IFXMIPS_MEI_RUN:
2598                         if (arc_halt_flag == 1) {
2599                                 meiRunArc ();
2600                         }
2601                         break;
2602                 case IFXMIPS_MEI_CMV_WINHOST:
2603                         if (MEI_MUTEX_LOCK (mei_sema))
2604                                 return -ERESTARTSYS;
2605
2606                         if (!from_kernel)
2607                                 copy_from_user ((char *) TxMessage, (char *) lon, MSG_LENGTH * 2);      //joelin
2608                         else
2609                                 memcpy (TxMessage, (char *) lon,
2610                                         MSG_LENGTH * 2);
2611
2612                         if (meiCMV (TxMessage, YES_REPLY, RxMessage) !=
2613                             MEI_SUCCESS) {
2614                                 printk
2615                                         ("\n\nWINHOST CMV fail :TxMessage:%X %X %X %X, RxMessage:%X %X %X %X %X\n",
2616                                          TxMessage[0], TxMessage[1],
2617                                          TxMessage[2], TxMessage[3],
2618                                          RxMessage[0], RxMessage[1],
2619                                          RxMessage[2], RxMessage[3],
2620                                          RxMessage[4]);
2621                                 meierr = MEI_FAILURE;
2622                         }
2623                         else {
2624                                 if (!from_kernel)       //joelin
2625                                         copy_to_user ((char *) lon,
2626                                                       (char *) RxMessage,
2627                                                       MSG_LENGTH * 2);
2628                                 else
2629                                         memcpy ((char *) lon,
2630                                                 (char *) RxMessage,
2631                                                 MSG_LENGTH * 2);
2632                         }
2633
2634                         MEI_MUTEX_UNLOCK (mei_sema);
2635                         break;
2636 #ifdef IFXMIPS_MEI_CMV_EXTRA
2637                 case IFXMIPS_MEI_CMV_READ:
2638                         copy_from_user ((char *) (&regrdwr), (char *) lon,
2639                                         sizeof (meireg));
2640                         meiLongwordRead ((u32*)regrdwr.iAddress, &(regrdwr.iData));
2641
2642                         copy_to_user((char *) lon, (char *) (&regrdwr), sizeof (meireg));
2643                         break;
2644
2645                 case IFXMIPS_MEI_CMV_WRITE:
2646                         copy_from_user ((char *) (&regrdwr), (char *) lon, sizeof (meireg));
2647                         meiLongwordWrite ((u32*)regrdwr.iAddress, regrdwr.iData);
2648                         break;
2649
2650                 case IFXMIPS_MEI_REMOTE:
2651                         copy_from_user ((char *) (&i), (char *) lon,
2652                                         sizeof (int));
2653                         if (i == 0) {
2654                                 meiMailboxInterruptsEnable ();
2655
2656                                 MEI_MUTEX_UNLOCK (mei_sema);
2657                         }
2658                         else if (i == 1) {
2659                                 meiMailboxInterruptsDisable ();
2660                                 if (MEI_MUTEX_LOCK (mei_sema))
2661                                         return -ERESTARTSYS;
2662                         }
2663                         else {
2664                                 printk
2665                                         ("\n\n IFXMIPS_MEI_REMOTE argument error");
2666                                 meierr = MEI_FAILURE;
2667                         }
2668                         break;
2669
2670                 case IFXMIPS_MEI_READDEBUG:
2671                 case IFXMIPS_MEI_WRITEDEBUG:
2672 #if 0                           //tc.chen:It is no necessary to acquire lock to read debug memory!!
2673                         if (MEI_MUTEX_LOCK (mei_sema))
2674                                 return -ERESTARTSYS;
2675 #endif
2676                         if (!from_kernel)
2677                                 copy_from_user ((char *) (&debugrdwr),
2678                                                 (char *) lon,
2679                                                 sizeof (debugrdwr));
2680                         else
2681                                 memcpy ((char *) (&debugrdwr), (char *) lon,
2682                                         sizeof (debugrdwr));
2683
2684                         if (command == IFXMIPS_MEI_READDEBUG)
2685                                 meiDebugRead (debugrdwr.iAddress,
2686                                               debugrdwr.buffer,
2687                                               debugrdwr.iCount);
2688                         else
2689                                 meiDebugWrite (debugrdwr.iAddress,
2690                                                debugrdwr.buffer,
2691                                                debugrdwr.iCount);
2692
2693                         if (!from_kernel)
2694                                 copy_to_user ((char *) lon, (char *) (&debugrdwr), sizeof (debugrdwr)); //dying gasp
2695 #if 0                           //tc.chen:It is no necessary to acquire lock to read debug memory!!
2696                         MEI_MUTEX_UNLOCK (mei_sema);
2697 #endif
2698                         break;
2699                 case IFXMIPS_MEI_RESET:
2700                 case IFXMIPS_MEI_REBOOT:
2701
2702 #ifdef CONFIG_IFXMIPS_MEI_MIB
2703                         mei_mib_adsl_link_down ();
2704 #endif
2705
2706 #ifdef IFX_ADSL_L3_MODE_SUPPORT
2707                         /* L3 Power Mode start */
2708                         if (check_co_l3_shutdown_request () == 1)       //co request
2709                         {
2710                                 // cpe received co L3 request
2711                                 l3_shutdown = 1;
2712                         }
2713                         /* L3 Power Mode end */
2714 #endif //IFX_ADSL_L3_MODE_SUPPORT
2715
2716                         meiResetARC ();
2717                         meiControlModeSwitch (MEI_MASTER_MODE);
2718                         //enable ac_clk signal  
2719                         _meiDebugLongWordRead (MEI_DEBUG_DEC_DMP1_MASK,
2720                                                CRI_CCR0, &arc_debug_data);
2721                         arc_debug_data |= ACL_CLK_MODE_ENABLE;
2722                         _meiDebugLongWordWrite (MEI_DEBUG_DEC_DMP1_MASK,
2723                                                 CRI_CCR0, arc_debug_data);
2724                         meiControlModeSwitch (JTAG_MASTER_MODE);
2725                         meiHaltArc ();
2726                         update_bar_register (nBar);
2727                         break;
2728                 case IFXMIPS_MEI_DOWNLOAD:
2729                         // DMA the boot code page(s)
2730                         printk ("Start download pages");
2731                         meiDownloadBootPages ();
2732                         break;
2733 #endif //IFXMIPS_MEI_CMV_EXTRA
2734                         //for clearEoC
2735 #ifdef IFXMIPS_CLEAR_EOC
2736                 case IFXMIPS_MEI_EOC_SEND:
2737                         if (!showtime) {
2738                                 return -EIO;
2739                         }
2740                         if (!from_kernel) {
2741                                 copy_from_user ((char *) (&debugrdwr),
2742                                                 (char *) lon,
2743                                                 sizeof (debugrdwr));
2744                                 eoc_skb =
2745                                         dev_alloc_skb (debugrdwr.iCount * 4);
2746                                 if (eoc_skb == NULL) {
2747                                         printk
2748                                                 ("\n\nskb alloc fail");
2749                                         break;
2750                                 }
2751
2752                                 eoc_skb->len = debugrdwr.iCount * 4;
2753                                 memcpy (skb_put
2754                                         (eoc_skb, debugrdwr.iCount * 4),
2755                                         (char *) debugrdwr.buffer,
2756                                         debugrdwr.iCount * 4);
2757                         }
2758                         else {
2759                                 eoc_skb = (struct sk_buff *) lon;
2760                         }
2761                         ifx_me_ceoc_send (eoc_skb);     //pass data to higher layer
2762                         break;
2763 #endif // IFXMIPS_CLEAR_EOC
2764                 case IFXMIPS_MEI_JTAG_ENABLE:
2765                         printk ("ARC JTAG Enable.\n");
2766                         *(IFXMIPS_GPIO_P0_DIR) = (*IFXMIPS_GPIO_P0_DIR) & (~0x800);     // set gpio11 to input
2767                         *(IFXMIPS_GPIO_P0_ALTSEL0) = ((*IFXMIPS_GPIO_P0_ALTSEL0) & (~0x800));
2768                         *(IFXMIPS_GPIO_P0_ALTSEL1) = ((*IFXMIPS_GPIO_P0_ALTSEL1) & (~0x800));
2769                         *IFXMIPS_GPIO_P0_OD = (*IFXMIPS_GPIO_P0_OD) | 0x800;
2770
2771                         //enable ARC JTAG
2772                         meiLongwordRead(IFXMIPS_RCU_RST, &reg_data);
2773                         meiLongwordWrite(IFXMIPS_RCU_RST, reg_data | IFXMIPS_RCU_RST_REQ_ARC_JTAG);
2774                         break;
2775
2776                 case GET_ADSL_LOOP_DIAGNOSTICS_MODE:
2777                         copy_to_user ((char *) lon, (char *) &loop_diagnostics_mode, sizeof(int));
2778                         break;
2779                 case LOOP_DIAGNOSTIC_MODE_COMPLETE:
2780                         loop_diagnostics_completed = 1;
2781 #ifdef CONFIG_IFXMIPS_MEI_MIB
2782                         // read adsl mode
2783                         makeCMV (H2D_CMV_READ, STAT, 1, 0, 1, NULL, TxMessage);
2784                         if (meiCMV (TxMessage, YES_REPLY, RxMessage) != MEI_SUCCESS) {
2785 #ifdef IFXMIPS_MEI_DEBUG_ON
2786                                 printk ("\n\nCMV fail, Group STAT Address 1 Index 0");
2787 #endif
2788                         }
2789                         adsl_mode = RxMessage[4];
2790
2791                         makeCMV (H2D_CMV_READ, STAT, 17, 0, 1, NULL, TxMessage);
2792                         if (meiCMV (TxMessage, YES_REPLY, RxMessage) != MEI_SUCCESS) {
2793 #ifdef IFXMIPS_MEI_DEBUG_ON
2794                                 printk ("\n\nCMV fail, Group STAT Address 1 Index 0");
2795 #endif
2796                         }
2797                         adsl_mode_extend = RxMessage[4];
2798 #endif
2799                         MEI_WAKEUP_EVENT (wait_queue_loop_diagnostic);
2800                         break;
2801                 case SET_ADSL_LOOP_DIAGNOSTICS_MODE:
2802                         if (lon != loop_diagnostics_mode) {
2803                                 loop_diagnostics_completed = 0;
2804                                 loop_diagnostics_mode = lon;
2805 #if 0 //08/12/2006 tc.chen : autoboot daemon should reset dsl
2806                                 mei_ioctl ((MEI_inode_t *) 0, NULL,
2807                                            IFXMIPS_MEI_REBOOT,
2808                                            (unsigned long) NULL);
2809 #endif
2810                         }
2811                         break;
2812                 case IS_ADSL_LOOP_DIAGNOSTICS_MODE_COMPLETE:
2813                         copy_to_user ((char *) lon,
2814                                       (char *) &loop_diagnostics_completed,
2815                                       sizeof (int));
2816                         break;
2817 #ifdef IFX_ADSL_L3_MODE_SUPPORT
2818                         /* L3 Power Mode Start */
2819                 case GET_POWER_MANAGEMENT_MODE:
2820                         i = get_l3_power_status ();
2821                         copy_to_user ((char *) lon, (char *) &i,
2822                                       sizeof (int));
2823                         break;
2824                 case SET_L3_POWER_MODE:
2825                         i = 1;
2826                         copy_from_user ((char *) &i, (char *) lon,
2827                                         sizeof (int));
2828                         if (i == 0) {
2829                                 return set_l3_shutdown ();
2830                         }
2831                         else {
2832                                 return set_l3_power_on ();
2833                         }
2834                         break;
2835                         /* L3 Power Mode End */
2836 #endif //IFX_ADSL_L3_MODE_SUPPORT
2837 #ifdef IFX_ADSL_DUAL_LATENCY_SUPPORT
2838                 case GET_ADSL_DUAL_LATENCY:
2839                         i = mei_is_dual_latency_enabled ();
2840                         if (i < 0)
2841                                 return i;
2842                         copy_to_user ((char *) lon, (char *) &i,
2843                                       sizeof (int));
2844                         break;
2845                 case SET_ADSL_DUAL_LATENCY:
2846                         i = 0;
2847                         copy_from_user ((char *) &i, (char *) lon,
2848                                         sizeof (int));
2849                         if (i > DUAL_LATENCY_US_DS_ENABLE) {
2850                                 return -EINVAL;
2851                         }
2852                         if (i != bDualLatency) {
2853                                 bDualLatency = i;
2854                                 i = 1;  // DualLatency update,need to reboot arc
2855                         }
2856                         else {
2857                                 i = 0;  // DualLatency is the same
2858                         }
2859                         if (modem_ready && i)   // modem is already start, reboot arc to apply Dual Latency changed
2860                         {
2861                                 mei_ioctl ((MEI_inode_t *) 0, NULL,
2862                                            IFXMIPS_MEI_REBOOT,
2863                                            (unsigned long) NULL);
2864                         }
2865                         break;
2866
2867 #endif
2868                 case QUIET_MODE_GET:
2869                         copy_to_user ((char *) lon, (char *) &quiet_mode_flag,
2870                                       sizeof (int));
2871                         break;
2872                 case QUIET_MODE_SET:
2873                         copy_from_user ((char *) &i, (char *) lon,
2874                                         sizeof (int));
2875                         if (i > 1 || i < 0)
2876                                 return -EINVAL;
2877                         if (i == 1) {
2878                                 u16 CMVMSG[MSG_LENGTH];
2879                                 u16 data = 0;
2880                                 makeCMV (H2D_CMV_WRITE, INFO, 94, 0, 1, &data, CMVMSG); // set tx power to 0
2881                                 meierr = mei_ioctl ((struct inode *) 0, NULL,
2882                                                     IFXMIPS_MEI_CMV_WINHOST,
2883                                                     (unsigned long) CMVMSG);
2884                         }
2885                         quiet_mode_flag = i;
2886                         break;
2887                 case SHOWTIME_LOCK_GET:
2888                         copy_to_user ((char *) lon,
2889                                       (char *) &showtime_lock_flag,
2890                                       sizeof (int));
2891                         break;
2892                 case SHOWTIME_LOCK_SET:
2893                         copy_from_user ((char *) &i, (char *) lon,
2894                                         sizeof (int));
2895                         if (i > 1 || i < 0)
2896                                 return -EINVAL;
2897                         showtime_lock_flag = i;
2898                         break;
2899                 case AUTOBOOT_ENABLE_SET:
2900                         copy_from_user ((char *) &i, (char *) lon,
2901                                         sizeof (int));
2902                         if (i > 1 || i < 0)
2903                                 return -EINVAL;
2904                         autoboot_enable_flag = i;
2905                         break;
2906                 default:
2907                         printk
2908                                 ("The ioctl command(0x%X is not supported!\n",
2909                                  command);
2910                         meierr = -ENOIOCTLCMD;
2911                 }
2912         }
2913         return meierr;
2914 }                               //mei_ioctl
2915
2916 ////////////////////     procfs debug    ///////////////////////////
2917
2918 #ifdef CONFIG_PROC_FS
2919 static int
2920 proc_read (struct file *file, char *buf, size_t nbytes, loff_t * ppos)
2921 {
2922         int i_ino = (file->f_dentry->d_inode)->i_ino;
2923         char outputbuf[64];
2924         int count = 0;
2925         int i;
2926         u32 version = 0;
2927         reg_entry_t *current_reg = NULL;
2928         u16 RxMessage[MSG_LENGTH] __attribute__ ((aligned (4)));
2929         u16 TxMessage[MSG_LENGTH] __attribute__ ((aligned (4)));
2930
2931         for (i = 0; i < NUM_OF_REG_ENTRY; i++) {
2932                 if (regs[i].low_ino == i_ino) {
2933                         current_reg = &regs[i];
2934                         break;
2935                 }
2936         }
2937         if (current_reg == NULL)
2938                 return -EINVAL;
2939
2940         if (current_reg->flag == (int *) 8) {
2941                 ///proc/mei/version
2942                 //format:
2943                 //Firmware version: major.minor.sub_version.int_version.rel_state.spl_appl
2944                 ///Firmware Date Time Code: date/month min:hour
2945                 if (*ppos > 0)  /* Assume reading completed in previous read */
2946                         return 0;       // indicates end of file
2947                 if (MEI_MUTEX_LOCK (mei_sema))
2948                         return -ERESTARTSYS;
2949
2950                 if (indicator_count < 1) {
2951                         MEI_MUTEX_UNLOCK (mei_sema);
2952                         return -EAGAIN;
2953                 }
2954                 //major:bits 0-7 
2955                 //minor:bits 8-15
2956                 makeCMV (H2D_CMV_READ, INFO, 54, 0, 1, NULL, TxMessage);
2957                 if (meiCMV (TxMessage, YES_REPLY, RxMessage) != MEI_SUCCESS) {
2958                         MEI_MUTEX_UNLOCK (mei_sema);
2959                         return -EIO;
2960                 }
2961                 version = RxMessage[4];
2962                 count = sprintf (outputbuf, "%d.%d.", (version) & 0xff,
2963                                  (version >> 8) & 0xff);
2964
2965                 //sub_version:bits 4-7
2966                 //int_version:bits 0-3
2967                 //spl_appl:bits 8-13
2968                 //rel_state:bits 14-15
2969                 makeCMV (H2D_CMV_READ, INFO, 54, 1, 1, NULL, TxMessage);
2970                 if (meiCMV (TxMessage, YES_REPLY, RxMessage) != MEI_SUCCESS) {
2971                         MEI_MUTEX_UNLOCK (mei_sema);
2972                         return -EFAULT;
2973                 }
2974                 version = RxMessage[4];
2975                 count += sprintf (outputbuf + count, "%d.%d.%d.%d",
2976                                   (version >> 4) & 0xf,
2977                                   version & 0xf,
2978                                   (version >> 14) & 0x3,
2979                                   (version >> 8) & 0x3f);
2980                 //Date:bits 0-7
2981                 //Month:bits 8-15
2982                 makeCMV (H2D_CMV_READ, INFO, 55, 0, 1, NULL, TxMessage);
2983                 if (meiCMV (TxMessage, YES_REPLY, RxMessage) != MEI_SUCCESS) {
2984                         MEI_MUTEX_UNLOCK (mei_sema);
2985                         return -EIO;
2986                 }
2987                 version = RxMessage[4];
2988
2989                 //Hour:bits 0-7
2990                 //Minute:bits 8-15
2991                 makeCMV (H2D_CMV_READ, INFO, 55, 1, 1, NULL, TxMessage);
2992                 if (meiCMV (TxMessage, YES_REPLY, RxMessage) != MEI_SUCCESS) {
2993                         MEI_MUTEX_UNLOCK (mei_sema);
2994                         return -EFAULT;
2995                 }
2996                 version += (RxMessage[4] << 16);
2997                 count += sprintf (outputbuf + count, " %d/%d %d:%d\n",
2998                                   version & 0xff, (version >> 8) & 0xff,
2999                                   (version >> 25) & 0xff,
3000                                   (version >> 16) & 0xff);
3001                 MEI_MUTEX_UNLOCK (mei_sema);
3002
3003                 *ppos += count;
3004         }
3005         else if (current_reg->flag != (int *) Recent_indicator) {
3006                 if (*ppos > 0)  /* Assume reading completed in previous read */
3007                         return 0;       // indicates end of file
3008                 count = sprintf (outputbuf, "0x%08X\n\n",
3009                                  *(current_reg->flag));
3010                 *ppos += count;
3011                 if (count > nbytes)     /* Assume output can be read at one time */
3012                         return -EINVAL;
3013         }
3014         else {
3015                 if ((int) (*ppos) / ((int) 7) == 16)
3016                         return 0;       // indicate end of the message
3017                 count = sprintf (outputbuf, "0x%04X\n\n",
3018                                  *(((u16 *) (current_reg->flag)) +
3019                                    (int) (*ppos) / ((int) 7)));
3020                 *ppos += count;
3021         }
3022         if (copy_to_user (buf, outputbuf, count))
3023                 return -EFAULT;
3024         return count;
3025 }
3026
3027 static ssize_t
3028 proc_write (struct file *file, const char *buffer, size_t count,
3029             loff_t * ppos)
3030 {
3031         int i_ino = (file->f_dentry->d_inode)->i_ino;
3032         reg_entry_t *current_reg = NULL;
3033         int i;
3034         unsigned long newRegValue;
3035         char *endp;
3036
3037         for (i = 0; i < NUM_OF_REG_ENTRY; i++) {
3038                 if (regs[i].low_ino == i_ino) {
3039                         current_reg = &regs[i];
3040                         break;
3041                 }
3042         }
3043         if ((current_reg == NULL)
3044             || (current_reg->flag == (int *) Recent_indicator))
3045                 return -EINVAL;
3046
3047         newRegValue = simple_strtoul (buffer, &endp, 0);
3048         *(current_reg->flag) = (int) newRegValue;
3049         return (count + endp - buffer);
3050 }
3051 #endif //CONFIG_PROC_FS
3052
3053 //TODO, for loopback test
3054 #ifdef DFE_LOOPBACK
3055 #define mte_reg_base    (0x4800*4+0x20000)
3056
3057 /* Iridia Registers Address Constants */
3058 #define MTE_Reg(r)      (int)(mte_reg_base + (r*4))
3059
3060 #define IT_AMODE        MTE_Reg(0x0004)
3061
3062 #define OMBOX_BASE      0xDF80
3063 #define OMBOX1  (OMBOX_BASE+0x4)
3064 #define IMBOX_BASE      0xDFC0
3065
3066 #define TIMER_DELAY     (1024)
3067 #define BC0_BYTES       (32)
3068 #define BC1_BYTES       (30)
3069 #define NUM_MB          (12)
3070 #define TIMEOUT_VALUE   2000
3071
3072 static void
3073 BFMWait (u32 cycle)
3074 {
3075         u32 i;
3076         for (i = 0; i < cycle; i++);
3077 }
3078
3079 static void
3080 WriteRegLong (u32 addr, u32 data)
3081 {
3082         //*((volatile u32 *)(addr)) =  data; 
3083         IFXMIPS_WRITE_REGISTER_L (data, addr);
3084 }
3085
3086 static u32
3087 ReadRegLong (u32 addr)
3088 {
3089         // u32  rd_val;
3090         //rd_val = *((volatile u32 *)(addr));
3091         // return rd_val;
3092         return IFXMIPS_READ_REGISTER_L (addr);
3093 }
3094
3095 /* This routine writes the mailbox with the data in an input array */
3096 static void
3097 WriteMbox (u32 * mboxarray, u32 size)
3098 {
3099         meiDebugWrite (IMBOX_BASE, mboxarray, size);
3100         printk ("write to %X\n", IMBOX_BASE);
3101         meiLongwordWrite ( MEI_TO_ARC_INT, MEI_TO_ARC_MSGAV);
3102 }
3103
3104 /* This routine reads the output mailbox and places the results into an array */
3105 static void
3106 ReadMbox (u32 * mboxarray, u32 size)
3107 {
3108         meiDebugRead (OMBOX_BASE, mboxarray, size);
3109         printk ("read from %X\n", OMBOX_BASE);
3110 }
3111
3112 static void
3113 MEIWriteARCValue (u32 address, u32 value)
3114 {
3115         u32 i, check = 0;
3116
3117         /* Write address register */
3118         IFXMIPS_WRITE_REGISTER_L (address, MEI_DEBUG_WAD);
3119
3120         /* Write data register */
3121         IFXMIPS_WRITE_REGISTER_L (value, MEI_DEBUG_DATA);
3122
3123         /* wait until complete - timeout at 40 */
3124         for (i = 0; i < 40; i++) {
3125                 check = IFXMIPS_READ_REGISTER_L (ARC_TO_MEI_INT);
3126
3127                 if ((check & ARC_TO_MEI_DBG_DONE))
3128                         break;
3129         }
3130         /* clear the flag */
3131         IFXMIPS_WRITE_REGISTER_L (ARC_TO_MEI_DBG_DONE, ARC_TO_MEI_INT);
3132 }
3133
3134 void
3135 arc_code_page_download (uint32_t arc_code_length, uint32_t * start_address)
3136 {
3137         int count;
3138         printk ("try to download pages,size=%d\n", arc_code_length);
3139         meiControlModeSwitch (MEI_MASTER_MODE);
3140         if (arc_halt_flag == 0) {
3141                 meiHaltArc ();
3142         }
3143         meiLongwordWrite ( MEI_XFR_ADDR, 0);
3144         for (count = 0; count < arc_code_length; count++) {
3145                 meiLongwordWrite ( MEI_DATA_XFR,
3146                                   *(start_address + count));
3147         }
3148         meiControlModeSwitch (JTAG_MASTER_MODE);
3149 }
3150 static int
3151 load_jump_table (unsigned long addr)
3152 {
3153         int i;
3154         uint32_t addr_le, addr_be;
3155         uint32_t jump_table[32];
3156         for (i = 0; i < 16; i++) {
3157                 addr_le = i * 8 + addr;
3158                 addr_be = ((addr_le >> 16) & 0xffff);
3159                 addr_be |= ((addr_le & 0xffff) << 16);
3160                 jump_table[i * 2 + 0] = 0x0f802020;
3161                 jump_table[i * 2 + 1] = addr_be;
3162                 //printk("jt %X %08X %08X\n",i,jump_table[i*2+0],jump_table[i*2+1]);
3163         }
3164         arc_code_page_download (32, &jump_table[0]);
3165         return 0;
3166 }
3167
3168 void
3169 dfe_loopback_irq_handler (void)
3170 {
3171         uint32_t rd_mbox[10];
3172
3173         memset (&rd_mbox[0], 0, 10 * 4);
3174         ReadMbox (&rd_mbox[0], 6);
3175         if (rd_mbox[0] == 0x0) {
3176                 printk ("Get ARC_ACK\n");
3177                 got_int = 1;
3178         }
3179         else if (rd_mbox[0] == 0x5) {
3180                 printk ("Get ARC_BUSY\n");
3181                 got_int = 2;
3182         }
3183         else if (rd_mbox[0] == 0x3) {
3184                 printk ("Get ARC_EDONE\n");
3185                 if (rd_mbox[1] == 0x0) {
3186                         got_int = 3;
3187                         printk ("Get E_MEMTEST\n");
3188                         if (rd_mbox[2] != 0x1) {
3189                                 got_int = 4;
3190                                 printk ("Get Result %X\n",
3191                                                  rd_mbox[2]);
3192                         }
3193                 }
3194         }
3195         meiLongwordWrite ( ARC_TO_MEI_INT, ARC_TO_MEI_DBG_DONE);
3196         MEI_MASK_AND_ACK_IRQ (IFXMIPS_MEI_INT);
3197         disable_irq (IFXMIPS_MEI_INT);
3198         //got_int = 1;
3199         return;
3200 }
3201
3202 static void
3203 wait_mem_test_result (void)
3204 {
3205         uint32_t mbox[5];
3206         mbox[0] = 0;
3207         printk ("Waiting Starting\n");
3208         while (mbox[0] == 0) {
3209                 ReadMbox (&mbox[0], 5);
3210         }
3211         printk ("Try to get mem test result.\n");
3212         ReadMbox (&mbox[0], 5);
3213         if (mbox[0] == 0xA) {
3214                 printk ("Success.\n");
3215         }
3216         else if (mbox[0] == 0xA) {
3217                 printk
3218                         ("Fail,address %X,except data %X,receive data %X\n",
3219                          mbox[1], mbox[2], mbox[3]);
3220         }
3221         else {
3222                 printk ("Fail\n");
3223         }
3224 }
3225
3226 static int
3227 arc_ping_testing (void)
3228 {
3229 #define MEI_PING 0x00000001
3230         uint32_t wr_mbox[10], rd_mbox[10];
3231         int i;
3232         for (i = 0; i < 10; i++) {
3233                 wr_mbox[i] = 0;
3234                 rd_mbox[i] = 0;
3235         }
3236
3237         printk ("send ping msg\n");
3238         wr_mbox[0] = MEI_PING;
3239         WriteMbox (&wr_mbox[0], 10);
3240
3241         while (got_int == 0) {
3242                 MEI_WAIT (100);
3243         }
3244
3245         printk ("send start event\n");
3246         got_int = 0;
3247
3248         wr_mbox[0] = 0x4;
3249         wr_mbox[1] = 0;
3250         wr_mbox[2] = 0;
3251         wr_mbox[3] = (uint32_t) 0xf5acc307e;
3252         wr_mbox[4] = 5;
3253         wr_mbox[5] = 2;
3254         wr_mbox[6] = 0x1c000;
3255         wr_mbox[7] = 64;
3256         wr_mbox[8] = 0;
3257         wr_mbox[9] = 0;
3258         WriteMbox (&wr_mbox[0], 10);
3259         enable_irq (IFXMIPS_MEI_INT);
3260         //printk("meiMailboxWrite ret=%d\n",i);
3261         meiLongwordWrite ( MEI_TO_ARC_INT, MEI_TO_ARC_MSGAV);
3262         printk ("sleeping\n");
3263         while (1) {
3264                 if (got_int > 0) {
3265
3266                         if (got_int > 3)
3267                                 printk ("got_int >>>> 3\n");
3268                         else
3269                                 printk ("got int = %d\n", got_int);
3270                         got_int = 0;
3271                         //schedule();
3272                         enable_irq (IFXMIPS_MEI_INT);
3273                 }
3274                 //mbox_read(&rd_mbox[0],6);
3275                 MEI_WAIT (100);
3276         }
3277 }
3278
3279 static MEI_ERROR
3280 DFE_Loopback_Test (void)
3281 {
3282         int i = 0;
3283         u32 arc_debug_data = 0, temp;
3284
3285         meiResetARC ();
3286         // start the clock
3287         arc_debug_data = ACL_CLK_MODE_ENABLE;
3288         meiDebugWrite (CRI_CCR0, &arc_debug_data, 1);
3289
3290 #if defined( DFE_PING_TEST )|| defined( DFE_ATM_LOOPBACK)
3291         // WriteARCreg(AUX_XMEM_LTEST,0);
3292         meiControlModeSwitch (MEI_MASTER_MODE);
3293 #define AUX_XMEM_LTEST 0x128
3294         _meiDebugLongWordWrite (MEI_DEBUG_DEC_AUX_MASK, AUX_XMEM_LTEST, 0);
3295         meiControlModeSwitch (JTAG_MASTER_MODE);
3296
3297         // WriteARCreg(AUX_XDMA_GAP,0); 
3298         meiControlModeSwitch (MEI_MASTER_MODE);
3299 #define AUX_XDMA_GAP 0x114
3300         _meiDebugLongWordWrite (MEI_DEBUG_DEC_AUX_MASK, AUX_XDMA_GAP, 0);
3301         meiControlModeSwitch (JTAG_MASTER_MODE);
3302
3303         meiControlModeSwitch (MEI_MASTER_MODE);
3304         temp = 0;
3305         _meiDebugLongWordWrite (MEI_DEBUG_DEC_AUX_MASK,
3306                                 (u32) MEI_XDATA_BASE_SH, temp);
3307         meiControlModeSwitch (JTAG_MASTER_MODE);
3308
3309         i = alloc_processor_memory (SDRAM_SEGMENT_SIZE * 16, adsl_mem_info);
3310         if (i >= 0) {
3311                 int idx;
3312
3313                 for (idx = 0; idx < i; idx++) {
3314                         adsl_mem_info[idx].type = FREE_RELOAD;
3315                         IFXMIPS_WRITE_REGISTER_L ((((uint32_t)
3316                                                    adsl_mem_info[idx].
3317                                                    address) & 0x0fffffff),
3318                                                  MEI_XMEM_BAR_BASE + idx * 4);
3319                         printk ("bar%d(%X)=%X\n", idx,
3320                                          MEI_XMEM_BAR_BASE + idx * 4,
3321                                          (((uint32_t) adsl_mem_info[idx].
3322                                            address) & 0x0fffffff));
3323                         memset ((u8 *) adsl_mem_info[idx].address, 0,
3324                                 SDRAM_SEGMENT_SIZE);
3325                 }
3326
3327                 meiLongwordWrite ( MEI_XDATA_BASE_SH, ((unsigned long)
3328                                                             adsl_mem_info
3329                                                             [XDATA_REGISTER].
3330                                                             address) &
3331                                   0x0FFFFFFF);
3332
3333         }
3334         else {
3335                 printk ("cannot load image: no memory\n\n");
3336                 return MEI_FAILURE;
3337         }
3338         //WriteARCreg(AUX_IC_CTRL,2);
3339         meiControlModeSwitch (MEI_MASTER_MODE);
3340 #define AUX_IC_CTRL 0x11
3341         _meiDebugLongWordWrite (MEI_DEBUG_DEC_AUX_MASK, AUX_IC_CTRL, 2);
3342         meiControlModeSwitch (JTAG_MASTER_MODE);
3343
3344         meiHaltArc ();
3345
3346 #ifdef DFE_PING_TEST
3347
3348         printk ("ping test image size=%d\n", sizeof (code_array));
3349         memcpy ((u8 *) (adsl_mem_info[0].address + 0x1004), &code_array[0],
3350                 sizeof (code_array));
3351         load_jump_table (0x80000 + 0x1004);
3352
3353 #endif //DFE_PING_TEST
3354
3355         printk ("ARC ping test code download complete\n");
3356 #endif //defined( DFE_PING_TEST )|| defined( DFE_ATM_LOOPBACK)
3357 #ifdef DFE_MEM_TEST
3358         meiLongwordWrite (ARC_TO_MEI_INT_MASK, MSGAV_EN);
3359
3360         arc_code_page_download (1537, &mem_test_code_array[0]);
3361         printk ("ARC mem test code download complete\n");
3362 #endif //DFE_MEM_TEST
3363 #ifdef DFE_ATM_LOOPBACK
3364         arc_debug_data = 0xf;
3365         arc_code_page_download (1077, &code_array[0]);
3366         // Start Iridia IT_AMODE (in dmp access) why is it required?
3367         meiDebugWrite (0x32010, &arc_debug_data, 1);
3368 #endif //DFE_ATM_LOOPBACK
3369         meiMailboxInterruptsEnable ();
3370         meiRunArc ();
3371
3372 #ifdef DFE_PING_TEST
3373         arc_ping_testing ();
3374 #endif //DFE_PING_TEST
3375 #ifdef DFE_MEM_TEST
3376         wait_mem_test_result ();
3377 #endif //DFE_MEM_TEST
3378
3379         free_image_buffer (FREE_ALL);
3380         return MEI_SUCCESS;
3381 }
3382
3383 #endif //DFE_LOOPBACK
3384 //end of TODO, for loopback test
3385
3386 #if defined(CONFIG_IFXMIPS_MEI_LED) && defined(DATA_LED_SUPPORT)
3387
3388 /* 
3389  *  Led Thread Main function
3390  */
3391 static int
3392 led_poll (void *unused)
3393 {
3394         struct task_struct *tsk = current;
3395
3396         daemonize("mei_led_poll");
3397         strcpy (tsk->comm, "atm_led");
3398         sigfillset (&tsk->blocked);
3399
3400         stop_led_module = 0;    //begin polling ...
3401
3402         while (!stop_led_module) {
3403                 if (led_status_on || led_need_to_flash) {
3404                         adsl_led_flash_task ();
3405                 }
3406                 if (led_status_on)      //sleep 200 ms to check if need to turn led off
3407                 {
3408                         interruptible_sleep_on_timeout
3409                                 (&wait_queue_led_polling, 25);
3410                 }
3411                 else {
3412                         interruptible_sleep_on (&wait_queue_led_polling);
3413                 }
3414         }
3415         return 0;
3416 }
3417
3418 /* 
3419  * API for atm driver to notify led thread a data coming/sending 
3420  */
3421 #if defined (CONFIG_ATM_IFXMIPS)
3422 static int
3423 adsl_led_flash (void)
3424 {
3425         if (!modem_ready)
3426                 return 0;
3427
3428         if (led_status_on == 0 && led_need_to_flash == 0)
3429         {
3430                 wake_up_interruptible (&wait_queue_led_polling);        //wake up and clean led module 
3431         }
3432         led_need_to_flash = 1;  //asking to flash led
3433
3434         return 0;
3435 }
3436 #endif
3437 /*
3438  * Main task for led controlling.
3439  */
3440 static int
3441 adsl_led_flash_task (void)
3442 {
3443 #ifdef DATA_LED_ADSL_FW_HANDLE
3444         u16 one = 1;
3445         u16 zero = 0;
3446         u16 data = 0x0600;
3447         u16 CMVMSG[MSG_LENGTH];
3448 #endif
3449
3450 //      printk("Task Running...\n");    //joelin  test
3451
3452         if (!showtime) {
3453                 led_need_to_flash = 0;
3454                 led_status_on = 0;
3455                 return 0;
3456         }
3457
3458         if (led_status_on == 0 && led_need_to_flash == 1) {
3459
3460 #ifdef DATA_LED_ADSL_FW_HANDLE
3461                 data = 0x0901;  //flash
3462                 send_cmv (H2D_CMV_WRITE, INFO, 91, 5, 1, &data, CMVMSG);        //use GPIO9 for TR68 data led .flash.
3463 #else
3464                 ifxmips_led_blink_set(0x0); // data
3465                 ifxmips_led_blink_set(0x1); // link
3466 #endif
3467                 led_status_on = 1;
3468
3469         }
3470         else if (led_status_on == 1 && led_need_to_flash == 0) {
3471 #ifdef DATA_LED_ADSL_FW_HANDLE
3472 #ifdef DATA_LED_ON_MODE
3473                 data = 0x0903;  //use GPIO9 for TR68 data led .turn on.
3474 #else
3475                 data = 0x0900;  //off
3476 #endif
3477                 printk ("off %04X\n", data);
3478                 send_cmv (H2D_CMV_WRITE, INFO, 91, 5, 1, &data, CMVMSG);        //use GPIO9 for TR68 data led .off.
3479 #else
3480 #endif
3481                 led_status_on = 0;
3482         }
3483         led_need_to_flash = 0;
3484         return 0;
3485 }
3486
3487 /* 
3488  * Led initialization function
3489  * This function create a thread to polling atm traffic and do led blanking
3490  */
3491 static int
3492 ifxmips_mei_led_init (void)
3493 {
3494         init_waitqueue_head (&wait_queue_led_polling);  // adsl led for led function
3495         kernel_thread (led_poll, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD);
3496         return 0;
3497 }
3498
3499 /* 
3500  * Led destory function
3501  */
3502 static int
3503 ifxmips_mei_led_cleanup (void)
3504 {
3505         stop_led_module = 1;    //wake up and clean led module 
3506         wake_up_interruptible (&wait_queue_led_polling);        //wake up and clean led module   
3507         return 0;
3508 }
3509 #endif //#ifdef CONFIG_IFXMIPS_MEI_LED
3510
3511 ////////////////////////////////////////////////////////////////////////////
3512 int __init
3513 ifxmips_mei_init_module (void)
3514 {
3515         struct proc_dir_entry *entry;
3516         int i;
3517         u32 temp;
3518 #ifdef CONFIG_DEVFS_FS
3519         char buf[10];
3520 #endif
3521         reg_entry_t regs_temp[PROC_ITEMS] =     // Items being debugged
3522         {
3523                 /*  {   flag,                   name,              description } */
3524                 {&arcmsgav, "arcmsgav", "arc to mei message ", 0},
3525                 {&cmv_reply, "cmv_reply", "cmv needs reply", 0},
3526                 {&cmv_waiting, "cmv_waiting",
3527                  "waiting for cmv reply from arc", 0},
3528                 {&indicator_count, "indicator_count",
3529                  "ARC to MEI indicator count", 0},
3530                 {&cmv_count, "cmv_count", "MEI to ARC CMVs", 0},
3531                 {&reply_count, "reply_count", "ARC to MEI Reply", 0},
3532                 {(int *) Recent_indicator, "Recent_indicator",
3533                  "most recent indicator", 0},
3534                 {(int *) 8, "version", "version of firmware", 0},
3535         };
3536         do_gettimeofday (&time_disconnect);
3537
3538         printk ("Danube MEI version:%s\n", IFXMIPS_MEI_VERSION);
3539
3540         memcpy ((char *) regs, (char *) regs_temp, sizeof (regs_temp));
3541         MEI_MUTEX_INIT (mei_sema, 1);   // semaphore initialization, mutex
3542         MEI_INIT_WAKELIST ("arcq", wait_queue_arcmsgav);        // for ARCMSGAV
3543         MEI_INIT_WAKELIST ("arcldq", wait_queue_loop_diagnostic);       // for loop diagnostic function
3544 #ifdef IFX_ADSL_L3_MODE_SUPPORT
3545         MEI_INIT_WAKELIST ("arcl3q", wait_queue_l3);    // for l3 power mode
3546 #endif //IFX_ADSL_L3_MODE_SUPPORT
3547
3548
3549         memset (&adsl_mem_info[0], 0, sizeof (smmu_mem_info_t) * MAX_BAR_REGISTERS);
3550 #if defined(CONFIG_IFXMIPS_MEI_LED) && defined(DATA_LED_SUPPORT)
3551         printk("not enabling mei leds due to bug that makes the board hang\n");
3552 //      ifxmips_mei_led_init ();
3553 #endif
3554
3555 #ifdef CONFIG_IFXMIPS_MEI_MIB
3556         ifxmips_mei_mib_init ();
3557 #endif
3558
3559 #ifdef IFXMIPS_CLEAR_EOC
3560         MEI_INIT_WAKELIST ("arceoc", wait_queue_hdlc_poll);
3561         ifxmips_mei_ceoc_init ();
3562 #endif
3563         // power up mei 
3564         temp = ifxmips_r32(IFXMIPS_PMU_PWDCR);
3565         temp &= 0xffff7dbe;
3566         ifxmips_w32(temp, IFXMIPS_PMU_PWDCR);
3567
3568 #if defined (CONFIG_ATM_IFXMIPS)
3569         IFX_ATM_LED_Callback_Register (adsl_led_flash);
3570 #endif
3571         if (register_chrdev (major, IFXMIPS_MEI_DEVNAME, &mei_operations) != 0) {
3572                 printk("\n\n unable to register major for ifxmips_mei!!!");
3573                 return -ENODEV;
3574         } else {
3575                 printk("registered ifxmips_mei on #%d\n", major);
3576         }
3577
3578         disable_irq(IFXMIPS_MEI_INT);
3579
3580         if (request_irq(IFXMIPS_MEI_INT, mei_interrupt_arcmsgav, 0, "ifxmips_mei_arcmsgav", NULL) != 0) {
3581                 printk("\n\n unable to register irq(%d) for ifxmips_mei!!!",
3582                         IFXMIPS_MEI_INT);
3583                 return -1;
3584         }
3585
3586 //      enable_irq(IFXMIPS_MEI_INT);
3587         // procfs
3588         meidir = proc_mkdir(MEI_DIRNAME, &proc_root);
3589         if (meidir == NULL)
3590         {
3591                 printk(": can't create /proc/" MEI_DIRNAME "\n\n");
3592                 return -ENOMEM;
3593         }
3594
3595         for (i = 0; i < NUM_OF_REG_ENTRY; i++) {
3596                 entry = create_proc_entry (regs[i].name,
3597                                            S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, meidir);
3598                 if (entry)
3599                 {
3600                         regs[i].low_ino = entry->low_ino;
3601                         entry->proc_fops = &proc_operations;
3602                 } else {
3603                         printk (": can't create /proc/" MEI_DIRNAME "/%s\n\n", regs[i].name);
3604                         return -ENOMEM;
3605                 }
3606         }
3607
3608         ///////////////////////////////// register net device ////////////////////////////
3609 #ifdef DFE_LOOPBACK
3610         DFE_Loopback_Test ();
3611 #endif //DFE_LOOPBACK
3612         return 0;
3613 }
3614
3615 void __exit
3616 ifxmips_mei_cleanup_module (void)
3617 {
3618         int i;
3619
3620 #if defined(CONFIG_IFXMIPS_MEI_LED) && defined(DATA_LED_SUPPORT)
3621         ifxmips_mei_led_cleanup ();
3622 #endif
3623         showtime = 0;           //joelin,clear task
3624
3625 #ifdef CONFIG_PROC_FS
3626         for (i = 0; i < NUM_OF_REG_ENTRY; i++)
3627                 remove_proc_entry (regs[i].name, meidir);
3628
3629         remove_proc_entry (MEI_DIRNAME, &proc_root);
3630 #endif //CONFIG_PROC_FS
3631
3632 #if defined (CONFIG_ATM_IFXMIPS)
3633         IFX_ATM_LED_Callback_Unregister (adsl_led_flash);
3634 #endif
3635         disable_irq (IFXMIPS_MEI_INT);
3636         free_irq(IFXMIPS_MEI_INT, NULL);
3637
3638 #ifdef CONFIG_DEVFS_FS
3639         devfs_unregister (mei_devfs_handle);
3640 #else
3641         unregister_chrdev (major, "ifxmips_mei");
3642 #endif
3643 #ifdef CONFIG_IFXMIPS_MEI_MIB
3644         ifxmips_mei_mib_cleanup ();
3645 #endif
3646
3647         free_image_buffer (FREE_ALL);
3648         return;
3649 }
3650
3651 EXPORT_SYMBOL (meiDebugRead);
3652 EXPORT_SYMBOL (meiDebugWrite);
3653 EXPORT_SYMBOL (ifx_me_hdlc_send);
3654 EXPORT_SYMBOL (ifx_mei_hdlc_read);
3655 MODULE_LICENSE ("GPL");
3656
3657 module_init (ifxmips_mei_init_module);
3658 module_exit (ifxmips_mei_cleanup_module);