5651b9f20ce91e17cab2933fc0e3e5b2170e3139
[oweals/openwrt.git] / package / ifxmips-dsl-api / src / ifxmips_mei.c
1 /******************************************************************************
2
3                                Copyright (c) 2009
4                             Infineon Technologies AG
5                      Am Campeon 1-12; 81726 Munich, Germany
6
7   For licensing information, see the file 'LICENSE' in the root folder of
8   this software module.
9
10 ******************************************************************************/
11
12 /*!
13   \defgroup AMAZON_S_MEI Amazon-S MEI Driver Module
14   \brief Amazon-S MEI driver module
15  */
16
17 /*!
18   \defgroup Internal Compile Parametere
19   \ingroup AMAZON_S_MEI
20   \brief exported functions for other driver use
21  */
22
23 /*!
24   \file amazon_s_mei_bsp.c
25   \ingroup AMAZON_S_MEI
26   \brief Amazon-S MEI driver file
27  */
28
29 #include <linux/kernel.h>
30 #include <linux/module.h>
31 #include <linux/version.h>
32 #include <linux/utsrelease.h>
33 #include <linux/types.h>
34 #include <linux/fs.h>
35 #include <linux/mm.h>
36 #include <linux/errno.h>
37 #include <linux/interrupt.h>
38 #include <linux/netdevice.h>
39 #include <linux/etherdevice.h>
40 #include <linux/proc_fs.h>
41 #include <linux/init.h>
42 #include <linux/ioport.h>
43 #include <linux/delay.h>
44 #include <asm/uaccess.h>
45 #include <asm/hardirq.h>
46 #include <asm/ifx/ifx_regs.h>
47 #include <asm/ifx/irq.h>
48 #include <asm/ifx/ifx_gpio.h>
49 //#include <asm/ifx/ifx_led.h>
50 #include <asm/ifx/ifx_pmu.h>
51 #include <asm/ifx/ifx_atm.h>
52 #define IFX_MEI_BSP
53 #include "ifxmips_mei_interface.h"
54
55 #define IFXMIPS_RCU_RST                   IFX_RCU_RST_REQ
56 #define IFXMIPS_RCU_RST_REQ_ARC_JTAG      IFX_RCU_RST_REQ_ARC_JTAG
57 #define IFXMIPS_RCU_RST_REQ_DFE           IFX_RCU_RST_REQ_DFE
58 #define IFXMIPS_RCU_RST_REQ_AFE           IFX_RCU_RST_REQ_AFE
59 #define IFXMIPS_FUSE_BASE_ADDR            IFX_FUSE_BASE_ADDR
60 #define IFXMIPS_ICU_IM0_IER               IFX_ICU_IM0_IER
61 #define IFXMIPS_ICU_IM2_IER               IFX_ICU_IM2_IER
62 #define IFXMIPS_MEI_INT                   IFX_MEI_INT
63 #define IFXMIPS_MEI_DYING_GASP_INT        IFX_MEI_DYING_GASP_INT
64 #define IFXMIPS_MEI_BASE_ADDR             IFX_MEI_SPACE_ACCESS
65 #define IFXMIPS_PMU_PWDCR                 IFX_PMU_PWDCR
66 #define IFXMIPS_MPS_CHIPID                IFX_MPS_CHIPID
67
68 #define ifxmips_port_reserve_pin          ifx_gpio_pin_reserve
69 #define ifxmips_port_set_dir_in           ifx_gpio_dir_in_set
70 #define ifxmips_port_clear_altsel0        ifx_gpio_altsel0_set
71 #define ifxmips_port_clear_altsel1        ifx_gpio_altsel1_clear
72 #define ifxmips_port_set_open_drain       ifx_gpio_open_drain_clear
73 #define ifxmips_port_free_pin             ifx_gpio_pin_free
74 #define ifxmips_mask_and_ack_irq          bsp_mask_and_ack_irq
75 #define IFXMIPS_MPS_CHIPID_VERSION_GET    IFX_MCD_CHIPID_VERSION_GET
76 #define ifxmips_r32(reg)                        __raw_readl(reg)
77 #define ifxmips_w32(val, reg)                   __raw_writel(val, reg)
78 #define ifxmips_w32_mask(clear, set, reg)       ifxmips_w32((ifxmips_r32(reg) & ~clear) | set, reg)
79
80 #define IFX_MEI_EMSG(fmt, args...) printk(KERN_ERR  "[%s %d]: " fmt,__FUNCTION__, __LINE__, ## args)
81 #define IFX_MEI_DMSG(fmt, args...) printk(KERN_INFO "[%s %d]: " fmt,__FUNCTION__, __LINE__, ## args)
82
83 #ifdef CONFIG_IFXMIPS_MEI_FW_LOOPBACK
84 //#define DFE_MEM_TEST
85 //#define DFE_PING_TEST
86 #define DFE_ATM_LOOPBACK
87
88 #ifdef DFE_PING_TEST
89 #include "dsp_xmem_arb_rand_em.h"
90 #endif
91
92 #ifdef DFE_MEM_TEST
93 #include "aai_mem_test.h"
94 #endif
95
96 #ifdef DFE_ATM_LOOPBACK
97 #include <asm/ifxmips/ifxmips_mei_fw_loopback.h>
98 #endif
99
100 void dfe_loopback_irq_handler (DSL_DEV_Device_t *pDev);
101
102 #endif //CONFIG_AMAZON_S_MEI_FW_LOOPBACK
103
104 DSL_DEV_Version_t bsp_mei_version = {
105         major:  5,
106         minor:  0,
107         revision:0
108 };
109 DSL_DEV_HwVersion_t bsp_chip_info;
110
111 #define IFX_MEI_DEVNAME "ifx_mei"
112 #define BSP_MAX_DEVICES 1
113
114 DSL_DEV_MeiError_t DSL_BSP_FWDownload (DSL_DEV_Device_t *, const char *, unsigned long, long *, long *);
115 DSL_DEV_MeiError_t DSL_BSP_Showtime (DSL_DEV_Device_t *, DSL_uint32_t, DSL_uint32_t);
116 DSL_DEV_MeiError_t DSL_BSP_AdslLedInit (DSL_DEV_Device_t *, DSL_DEV_LedId_t, DSL_DEV_LedType_t, DSL_DEV_LedHandler_t);
117 //DSL_DEV_MeiError_t DSL_BSP_AdslLedSet (DSL_DEV_Device_t *, DSL_DEV_LedId_t, DSL_DEV_LedMode_t);
118 DSL_DEV_MeiError_t DSL_BSP_MemoryDebugAccess (DSL_DEV_Device_t *, DSL_BSP_MemoryAccessType_t, DSL_uint32_t, DSL_uint32_t*, DSL_uint32_t);
119 DSL_DEV_MeiError_t DSL_BSP_SendCMV (DSL_DEV_Device_t *, u16 *, int, u16 *);
120
121 int DSL_BSP_KernelIoctls (DSL_DEV_Device_t *, unsigned int, unsigned long);
122
123 static DSL_DEV_MeiError_t IFX_MEI_RunAdslModem (DSL_DEV_Device_t *);
124 static DSL_DEV_MeiError_t IFX_MEI_CpuModeSet (DSL_DEV_Device_t *, DSL_DEV_CpuMode_t);
125 static DSL_DEV_MeiError_t IFX_MEI_DownloadBootCode (DSL_DEV_Device_t *);
126 static DSL_DEV_MeiError_t IFX_MEI_ArcJtagEnable (DSL_DEV_Device_t *, int);
127 static DSL_DEV_MeiError_t IFX_MEI_AdslMailboxIRQEnable (DSL_DEV_Device_t *, int);
128
129 static int IFX_MEI_GetPage (DSL_DEV_Device_t *, u32, u32, u32, u32 *, u32 *);
130 static int IFX_MEI_BarUpdate (DSL_DEV_Device_t *, int);
131
132 static ssize_t IFX_MEI_Write (DSL_DRV_file_t *, const char *, size_t, loff_t *);
133 static int IFX_MEI_UserIoctls (DSL_DRV_inode_t *, DSL_DRV_file_t *, unsigned int, unsigned long);
134 static int IFX_MEI_Open (DSL_DRV_inode_t *, DSL_DRV_file_t *);
135 static int IFX_MEI_Release (DSL_DRV_inode_t *, DSL_DRV_file_t *);
136
137 void AMAZON_SE_MEI_ARC_MUX_Test(void);
138
139 #ifdef CONFIG_PROC_FS
140 static int IFX_MEI_ProcRead (struct file *, char *, size_t, loff_t *);
141 static ssize_t IFX_MEI_ProcWrite (struct file *, const char *, size_t, loff_t *);
142
143 #define PROC_ITEMS 11
144 #define MEI_DIRNAME "ifxmips_mei"
145
146 static struct proc_dir_entry *meidir;
147 static struct file_operations IFX_MEI_ProcOperations = {
148       read:IFX_MEI_ProcRead,
149       write:IFX_MEI_ProcWrite,
150 };
151 static reg_entry_t regs[BSP_MAX_DEVICES][PROC_ITEMS];   //total items to be monitored by /proc/mei
152 #define NUM_OF_REG_ENTRY        (sizeof(regs[0])/sizeof(reg_entry_t))
153 #endif //CONFIG_PROC_FS
154
155 void IFX_MEI_ARC_MUX_Test(void);
156
157 static int adsl_dummy_ledcallback(void);
158
159 int (*ifx_mei_atm_showtime_enter)(struct port_cell_info *, void *) = NULL;
160 EXPORT_SYMBOL(ifx_mei_atm_showtime_enter);
161
162 int (*ifx_mei_atm_showtime_exit)(void) = NULL;
163 EXPORT_SYMBOL(ifx_mei_atm_showtime_exit);
164
165 static int (*g_adsl_ledcallback)(void) = adsl_dummy_ledcallback;
166
167 static unsigned int g_tx_link_rate[2] = {0};
168
169 static void *g_xdata_addr = NULL;
170
171 static u32 *mei_arc_swap_buff = NULL;   //  holding swap pages
172
173 extern void ifxmips_mask_and_ack_irq(unsigned int irq_nr);
174 #define MEI_MASK_AND_ACK_IRQ ifxmips_mask_and_ack_irq
175
176 static int dev_major = 105;
177
178 static struct file_operations bsp_mei_operations = {
179       owner:THIS_MODULE,
180       open:IFX_MEI_Open,
181       release:IFX_MEI_Release,
182       write:IFX_MEI_Write,
183       ioctl:IFX_MEI_UserIoctls,
184 };
185
186 static DSL_DEV_Device_t dsl_devices[BSP_MAX_DEVICES];
187
188 static ifx_mei_device_private_t
189         sDanube_Mei_Private[BSP_MAX_DEVICES];
190
191 static DSL_BSP_EventCallBack_t dsl_bsp_event_callback[DSL_BSP_CB_LAST + 1];
192
193 /**
194  * Write a value to register
195  * This function writes a value to danube register
196  *
197  * \param       ul_address      The address to write
198  * \param       ul_data         The value to write
199  * \ingroup     Internal
200  */
201 static void
202 IFX_MEI_LongWordWrite (u32 ul_address, u32 ul_data)
203 {
204         IFX_MEI_WRITE_REGISTER_L (ul_data, ul_address);
205         wmb();
206         return;
207 }
208
209 /**
210  * Write a value to register
211  * This function writes a value to danube register
212  *
213  * \param       pDev            the device pointer
214  * \param       ul_address      The address to write
215  * \param       ul_data         The value to write
216  * \ingroup     Internal
217  */
218 static void
219 IFX_MEI_LongWordWriteOffset (DSL_DEV_Device_t * pDev, u32 ul_address,
220                                    u32 ul_data)
221 {
222         IFX_MEI_WRITE_REGISTER_L (ul_data, pDev->base_address + ul_address);
223         wmb();
224         return;
225 }
226
227 /**
228  * Read the danube register
229  * This function read the value from danube register
230  *
231  * \param       ul_address      The address to write
232  * \param       pul_data        Pointer to the data
233  * \ingroup     Internal
234  */
235 static void
236 IFX_MEI_LongWordRead (u32 ul_address, u32 * pul_data)
237 {
238         *pul_data = IFX_MEI_READ_REGISTER_L (ul_address);
239         rmb();
240         return;
241 }
242
243 /**
244  * Read the danube register
245  * This function read the value from danube register
246  *
247  * \param       pDev            the device pointer
248  * \param       ul_address      The address to write
249  * \param       pul_data        Pointer to the data
250  * \ingroup     Internal
251  */
252 static void
253 IFX_MEI_LongWordReadOffset (DSL_DEV_Device_t * pDev, u32 ul_address,
254                                   u32 * pul_data)
255 {
256         *pul_data = IFX_MEI_READ_REGISTER_L (pDev->base_address + ul_address);
257         rmb();
258         return;
259 }
260
261 /**
262  * Write several DWORD datas to ARC memory via ARC DMA interface
263  * This function writes several DWORD datas to ARC memory via DMA interface.
264  *
265  * \param       pDev            the device pointer
266  * \param       destaddr        The address to write
267  * \param       databuff        Pointer to the data buffer
268  * \param       databuffsize    Number of DWORDs to write
269  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
270  * \ingroup     Internal
271  */
272 static DSL_DEV_MeiError_t
273 IFX_MEI_DMAWrite (DSL_DEV_Device_t * pDev, u32 destaddr,
274                         u32 * databuff, u32 databuffsize)
275 {
276         u32 *p = databuff;
277         u32 temp;
278
279         if (destaddr & 3)
280                 return DSL_DEV_MEI_ERR_FAILURE;
281
282         //      Set the write transfer address
283         IFX_MEI_LongWordWriteOffset (pDev, ME_DX_AD, destaddr);
284
285         //      Write the data pushed across DMA
286         while (databuffsize--) {
287                 temp = *p;
288                 if (destaddr == MEI_TO_ARC_MAILBOX)
289                         MEI_HALF_WORD_SWAP (temp);
290                 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DX_DATA, temp);
291                 p++;
292         }
293
294         return DSL_DEV_MEI_ERR_SUCCESS;
295
296 }
297
298 /**
299  * Read several DWORD datas from ARC memory via ARC DMA interface
300  * This function reads several DWORD datas from ARC memory via DMA interface.
301  *
302  * \param       pDev            the device pointer
303  * \param       srcaddr         The address to read
304  * \param       databuff        Pointer to the data buffer
305  * \param       databuffsize    Number of DWORDs to read
306  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
307  * \ingroup     Internal
308  */
309 static DSL_DEV_MeiError_t
310 IFX_MEI_DMARead (DSL_DEV_Device_t * pDev, u32 srcaddr, u32 * databuff,
311                        u32 databuffsize)
312 {
313         u32 *p = databuff;
314         u32 temp;
315
316         if (srcaddr & 3)
317                 return DSL_DEV_MEI_ERR_FAILURE;
318
319         //      Set the read transfer address
320         IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DX_AD, srcaddr);
321
322         //      Read the data popped across DMA
323         while (databuffsize--) {
324                 IFX_MEI_LongWordReadOffset (pDev, (u32) ME_DX_DATA, &temp);
325                 if (databuff == (u32 *) DSL_DEV_PRIVATE(pDev)->CMV_RxMsg)       // swap half word
326                         MEI_HALF_WORD_SWAP (temp);
327                 *p = temp;
328                 p++;
329         }
330
331         return DSL_DEV_MEI_ERR_SUCCESS;
332
333 }
334
335 /**
336  * Switch the ARC control mode
337  * This function switchs the ARC control mode to JTAG mode or MEI mode
338  *
339  * \param       pDev            the device pointer
340  * \param       mode            The mode want to switch: JTAG_MASTER_MODE or MEI_MASTER_MODE.
341  * \ingroup     Internal
342  */
343 static void
344 IFX_MEI_ControlModeSet (DSL_DEV_Device_t * pDev, int mode)
345 {
346         u32 temp = 0x0;
347
348         IFX_MEI_LongWordReadOffset (pDev, (u32) ME_DBG_MASTER, &temp);
349         switch (mode) {
350         case JTAG_MASTER_MODE:
351                 temp &= ~(HOST_MSTR);
352                 break;
353         case MEI_MASTER_MODE:
354                 temp |= (HOST_MSTR);
355                 break;
356         default:
357                 IFX_MEI_EMSG ("IFX_MEI_ControlModeSet: unkonwn mode [%d]\n", mode);
358                 return;
359         }
360         IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_MASTER, temp);
361 }
362
363 /**
364  * Disable ARC to MEI interrupt
365  *
366  * \param       pDev            the device pointer
367  * \ingroup     Internal
368  */
369 static void
370 IFX_MEI_IRQDisable (DSL_DEV_Device_t * pDev)
371 {
372         IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_MASK,  0x0);
373 }
374
375 /**
376  * Eable ARC to MEI interrupt
377  *
378  * \param       pDev            the device pointer
379  * \ingroup     Internal
380  */
381 static void
382 IFX_MEI_IRQEnable (DSL_DEV_Device_t * pDev)
383 {
384         IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_MASK, MSGAV_EN);
385 }
386
387 /**
388  * Poll for transaction complete signal
389  * This function polls and waits for transaction complete signal.
390  *
391  * \param       pDev            the device pointer
392  * \ingroup     Internal
393  */
394 static void
395 meiPollForDbgDone (DSL_DEV_Device_t * pDev)
396 {
397         u32 query = 0;
398         int i = 0;
399
400         while (i < WHILE_DELAY) {
401                 IFX_MEI_LongWordReadOffset (pDev, (u32) ME_ARC2ME_STAT,  &query);
402                 query &= (ARC_TO_MEI_DBG_DONE);
403                 if (query)
404                         break;
405                 i++;
406                 if (i == WHILE_DELAY) {
407                         IFX_MEI_EMSG ("PollforDbg fail!\n");
408                 }
409         }
410         IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_STAT, ARC_TO_MEI_DBG_DONE);  // to clear this interrupt
411 }
412
413 /**
414  * ARC Debug Memory Access for a single DWORD reading.
415  * This function used for direct, address-based access to ARC memory.
416  *
417  * \param       pDev            the device pointer
418  * \param       DEC_mode        ARC memory space to used
419  * \param       address         Address to read
420  * \param       data            Pointer to data
421  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
422  * \ingroup     Internal
423  */
424 static DSL_DEV_MeiError_t
425 _IFX_MEI_DBGLongWordRead (DSL_DEV_Device_t * pDev, u32 DEC_mode,
426                                 u32 address, u32 * data)
427 {
428         IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_DECODE, DEC_mode);
429         IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_RD_AD, address);
430         meiPollForDbgDone (pDev);
431         IFX_MEI_LongWordReadOffset (pDev, (u32) ME_DBG_DATA, data);
432         return DSL_DEV_MEI_ERR_SUCCESS;
433 }
434
435 /**
436  * ARC Debug Memory Access for a single DWORD writing.
437  * This function used for direct, address-based access to ARC memory.
438  *
439  * \param       pDev            the device pointer
440  * \param       DEC_mode        ARC memory space to used
441  * \param       address         The address to write
442  * \param       data            The data to write
443  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
444  * \ingroup     Internal
445  */
446 static DSL_DEV_MeiError_t
447 _IFX_MEI_DBGLongWordWrite (DSL_DEV_Device_t * pDev, u32 DEC_mode,
448                                  u32 address, u32 data)
449 {
450         IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_DECODE, DEC_mode);
451         IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_WR_AD, address);
452         IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_DATA, data);
453         meiPollForDbgDone (pDev);
454         return DSL_DEV_MEI_ERR_SUCCESS;
455 }
456
457 /**
458  * ARC Debug Memory Access for writing.
459  * This function used for direct, address-based access to ARC memory.
460  *
461  * \param       pDev            the device pointer
462  * \param       destaddr        The address to read
463  * \param       databuffer      Pointer to data
464  * \param       databuffsize    The number of DWORDs to read
465  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
466  * \ingroup     Internal
467  */
468
469 static DSL_DEV_MeiError_t
470 IFX_MEI_DebugWrite (DSL_DEV_Device_t * pDev, u32 destaddr,
471                           u32 * databuff, u32 databuffsize)
472 {
473         u32 i;
474         u32 temp = 0x0;
475         u32 address = 0x0;
476         u32 *buffer = 0x0;
477
478         //      Open the debug port before DMP memory write
479         IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
480
481         //      For the requested length, write the address and write the data
482         address = destaddr;
483         buffer = databuff;
484         for (i = 0; i < databuffsize; i++) {
485                 temp = *buffer;
486                 _IFX_MEI_DBGLongWordWrite (pDev, ME_DBG_DECODE_DMP1_MASK, address, temp);
487                 address += 4;
488                 buffer++;
489         }
490
491         //      Close the debug port after DMP memory write
492         IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
493
494         return DSL_DEV_MEI_ERR_SUCCESS;
495 }
496
497 /**
498  * ARC Debug Memory Access for reading.
499  * This function used for direct, address-based access to ARC memory.
500  *
501  * \param       pDev            the device pointer
502  * \param       srcaddr         The address to read
503  * \param       databuffer      Pointer to data
504  * \param       databuffsize    The number of DWORDs to read
505  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
506  * \ingroup     Internal
507  */
508 static DSL_DEV_MeiError_t
509 IFX_MEI_DebugRead (DSL_DEV_Device_t * pDev, u32 srcaddr, u32 * databuff, u32 databuffsize)
510 {
511         u32 i;
512         u32 temp = 0x0;
513         u32 address = 0x0;
514         u32 *buffer = 0x0;
515
516         //      Open the debug port before DMP memory read
517         IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
518
519         //      For the requested length, write the address and read the data
520         address = srcaddr;
521         buffer = databuff;
522         for (i = 0; i < databuffsize; i++) {
523                 _IFX_MEI_DBGLongWordRead (pDev, ME_DBG_DECODE_DMP1_MASK, address, &temp);
524                 *buffer = temp;
525                 address += 4;
526                 buffer++;
527         }
528
529         //      Close the debug port after DMP memory read
530         IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
531
532         return DSL_DEV_MEI_ERR_SUCCESS;
533 }
534
535 /**
536  * Send a message to ARC MailBox.
537  * This function sends a message to ARC Mailbox via ARC DMA interface.
538  *
539  * \param       pDev            the device pointer
540  * \param       msgsrcbuffer    Pointer to message.
541  * \param       msgsize         The number of words to write.
542  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
543  * \ingroup     Internal
544  */
545 static DSL_DEV_MeiError_t
546 IFX_MEI_MailboxWrite (DSL_DEV_Device_t * pDev, u16 * msgsrcbuffer,
547                             u16 msgsize)
548 {
549         int i;
550         u32 arc_mailbox_status = 0x0;
551         u32 temp = 0;
552         DSL_DEV_MeiError_t meiMailboxError = DSL_DEV_MEI_ERR_SUCCESS;
553
554         //      Write to mailbox
555         meiMailboxError =
556                 IFX_MEI_DMAWrite (pDev, MEI_TO_ARC_MAILBOX, (u32 *) msgsrcbuffer, msgsize / 2);
557         meiMailboxError =
558                 IFX_MEI_DMAWrite (pDev, MEI_TO_ARC_MAILBOXR, (u32 *) (&temp), 1);
559
560         //      Notify arc that mailbox write completed
561         DSL_DEV_PRIVATE(pDev)->cmv_waiting = 1;
562         IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ME2ARC_INT, MEI_TO_ARC_MSGAV);
563
564         i = 0;
565         while (i < WHILE_DELAY) {       // wait for ARC to clear the bit
566                 IFX_MEI_LongWordReadOffset (pDev, (u32) ME_ME2ARC_INT, &arc_mailbox_status);
567                 if ((arc_mailbox_status & MEI_TO_ARC_MSGAV) != MEI_TO_ARC_MSGAV)
568                         break;
569                 i++;
570                 if (i == WHILE_DELAY) {
571                         IFX_MEI_EMSG (">>> Timeout waiting for ARC to clear MEI_TO_ARC_MSGAV!!!"
572                               " MEI_TO_ARC message size = %d DWORDs <<<\n", msgsize/2);
573                         meiMailboxError = DSL_DEV_MEI_ERR_FAILURE;
574                 }
575         }
576
577         return meiMailboxError;
578 }
579
580 /**
581  * Read a message from ARC MailBox.
582  * This function reads a message from ARC Mailbox via ARC DMA interface.
583  *
584  * \param       pDev            the device pointer
585  * \param       msgsrcbuffer    Pointer to message.
586  * \param       msgsize         The number of words to read
587  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
588  * \ingroup     Internal
589  */
590 static DSL_DEV_MeiError_t
591 IFX_MEI_MailboxRead (DSL_DEV_Device_t * pDev, u16 * msgdestbuffer,
592                            u16 msgsize)
593 {
594         DSL_DEV_MeiError_t meiMailboxError = DSL_DEV_MEI_ERR_SUCCESS;
595         //      Read from mailbox
596         meiMailboxError =
597                 IFX_MEI_DMARead (pDev, ARC_TO_MEI_MAILBOX, (u32 *) msgdestbuffer, msgsize / 2);
598
599         //      Notify arc that mailbox read completed
600         IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_STAT, ARC_TO_MEI_MSGAV);
601
602         return meiMailboxError;
603 }
604
605 /**
606  * Download boot pages to ARC.
607  * This function downloads boot pages to ARC.
608  *
609  * \param       pDev            the device pointer
610  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
611  * \ingroup     Internal
612  */
613 static DSL_DEV_MeiError_t
614 IFX_MEI_DownloadBootPages (DSL_DEV_Device_t * pDev)
615 {
616         int boot_loop;
617         int page_size;
618         u32 dest_addr;
619
620         /*
621          **     DMA the boot code page(s)
622          */
623
624         for (boot_loop = 1;
625              boot_loop <
626              (DSL_DEV_PRIVATE(pDev)->img_hdr-> count); boot_loop++) {
627                 if ((DSL_DEV_PRIVATE(pDev)-> img_hdr->page[boot_loop].p_size) & BOOT_FLAG) {
628                         page_size = IFX_MEI_GetPage (pDev, boot_loop,
629                                                        GET_PROG, MAXSWAPSIZE,
630                                                        mei_arc_swap_buff,
631                                                        &dest_addr);
632                         if (page_size > 0) {
633                                 IFX_MEI_DMAWrite (pDev, dest_addr,
634                                                         mei_arc_swap_buff,
635                                                         page_size);
636                         }
637                 }
638                 if ((DSL_DEV_PRIVATE(pDev)-> img_hdr->page[boot_loop].d_size) & BOOT_FLAG) {
639                         page_size = IFX_MEI_GetPage (pDev, boot_loop,
640                                                        GET_DATA, MAXSWAPSIZE,
641                                                        mei_arc_swap_buff,
642                                                        &dest_addr);
643                         if (page_size > 0) {
644                                 IFX_MEI_DMAWrite (pDev, dest_addr,
645                                                         mei_arc_swap_buff,
646                                                         page_size);
647                         }
648                 }
649         }
650         return DSL_DEV_MEI_ERR_SUCCESS;
651 }
652
653 /**
654  * Initial efuse rar.
655  **/
656 static void
657 IFX_MEI_FuseInit (DSL_DEV_Device_t * pDev)
658 {
659         u32 data = 0;
660         IFX_MEI_DMAWrite (pDev, IRAM0_BASE, &data, 1);
661         IFX_MEI_DMAWrite (pDev, IRAM0_BASE + 4, &data, 1);
662         IFX_MEI_DMAWrite (pDev, IRAM1_BASE, &data, 1);
663         IFX_MEI_DMAWrite (pDev, IRAM1_BASE + 4, &data, 1);
664         IFX_MEI_DMAWrite (pDev, BRAM_BASE, &data, 1);
665         IFX_MEI_DMAWrite (pDev, BRAM_BASE + 4, &data, 1);
666         IFX_MEI_DMAWrite (pDev, ADSL_DILV_BASE, &data, 1);
667         IFX_MEI_DMAWrite (pDev, ADSL_DILV_BASE + 4, &data, 1);
668 }
669
670 /**
671  * efuse rar program
672  **/
673 static void
674 IFX_MEI_FuseProg (DSL_DEV_Device_t * pDev)
675 {
676         u32 reg_data, fuse_value;
677         int i = 0;
678
679         IFX_MEI_LongWordRead ((u32) IFXMIPS_RCU_RST, &reg_data);
680         while ((reg_data & 0x10000000) == 0) {
681                 IFX_MEI_LongWordRead ((u32) IFXMIPS_RCU_RST,  &reg_data);
682                 i++;
683                 /* 0x4000 translate to  about 16 ms@111M, so should be enough */
684                 if (i == 0x4000)
685                         return;
686         }
687         // STEP a: Prepare memory for external accesses
688         // Write fuse_en bit24
689         IFX_MEI_LongWordRead ((u32) IFXMIPS_RCU_RST, &reg_data);
690         IFX_MEI_LongWordWrite ((u32) IFXMIPS_RCU_RST, reg_data | (1 << 24));
691
692         IFX_MEI_FuseInit (pDev);
693         for (i = 0; i < 4; i++) {
694                 IFX_MEI_LongWordRead ((u32) (IFXMIPS_FUSE_BASE_ADDR) + i * 4, &fuse_value);
695                 switch (fuse_value & 0xF0000) {
696                 case 0x80000:
697                         reg_data = ((fuse_value & RX_DILV_ADDR_BIT_MASK) |
698                                  (RX_DILV_ADDR_BIT_MASK + 0x1));
699                         IFX_MEI_DMAWrite (pDev, ADSL_DILV_BASE, &reg_data, 1);
700                         break;
701                 case 0x90000:
702                         reg_data = ((fuse_value & RX_DILV_ADDR_BIT_MASK) |
703                                  (RX_DILV_ADDR_BIT_MASK + 0x1));
704                         IFX_MEI_DMAWrite (pDev, ADSL_DILV_BASE + 4, &reg_data, 1);
705                         break;
706                 case 0xA0000:
707                         reg_data = ((fuse_value & IRAM0_ADDR_BIT_MASK) |
708                                  (IRAM0_ADDR_BIT_MASK + 0x1));
709                         IFX_MEI_DMAWrite (pDev, IRAM0_BASE, &reg_data, 1);
710                         break;
711                 case 0xB0000:
712                         reg_data = ((fuse_value & IRAM0_ADDR_BIT_MASK) |
713                                  (IRAM0_ADDR_BIT_MASK + 0x1));
714                         IFX_MEI_DMAWrite (pDev, IRAM0_BASE + 4, &reg_data, 1);
715                         break;
716                 case 0xC0000:
717                         reg_data = ((fuse_value & IRAM1_ADDR_BIT_MASK) |
718                                  (IRAM1_ADDR_BIT_MASK + 0x1));
719                         IFX_MEI_DMAWrite (pDev, IRAM1_BASE, &reg_data, 1);
720                         break;
721                 case 0xD0000:
722                         reg_data = ((fuse_value & IRAM1_ADDR_BIT_MASK) |
723                                  (IRAM1_ADDR_BIT_MASK + 0x1));
724                         IFX_MEI_DMAWrite (pDev, IRAM1_BASE + 4, &reg_data, 1);
725                         break;
726                 case 0xE0000:
727                         reg_data = ((fuse_value & BRAM_ADDR_BIT_MASK) |
728                                  (BRAM_ADDR_BIT_MASK + 0x1));
729                         IFX_MEI_DMAWrite (pDev, BRAM_BASE, &reg_data, 1);
730                         break;
731                 case 0xF0000:
732                         reg_data = ((fuse_value & BRAM_ADDR_BIT_MASK) |
733                                  (BRAM_ADDR_BIT_MASK + 0x1));
734                         IFX_MEI_DMAWrite (pDev, BRAM_BASE + 4, &reg_data, 1);
735                         break;
736                 default:        // PPE efuse
737                         break;
738                 }
739         }
740         IFX_MEI_LongWordRead ((u32) IFXMIPS_RCU_RST, &reg_data);
741         IFX_MEI_LongWordWrite ((u32) IFXMIPS_RCU_RST, reg_data & ~(1 << 24));
742         IFX_MEI_LongWordRead ((u32) IFXMIPS_RCU_RST, &reg_data);
743 }
744
745 /**
746  * Enable DFE Clock
747  * This function enables DFE Clock
748  *
749  * \param       pDev            the device pointer
750  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
751  * \ingroup     Internal
752  */
753 static DSL_DEV_MeiError_t
754 IFX_MEI_EnableCLK (DSL_DEV_Device_t * pDev)
755 {
756         u32 arc_debug_data = 0;
757         IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
758         //enable ac_clk signal
759         _IFX_MEI_DBGLongWordRead (pDev, ME_DBG_DECODE_DMP1_MASK,
760                                         CRI_CCR0, &arc_debug_data);
761         arc_debug_data |= ACL_CLK_MODE_ENABLE;
762         _IFX_MEI_DBGLongWordWrite (pDev, ME_DBG_DECODE_DMP1_MASK,
763                                          CRI_CCR0, arc_debug_data);
764         IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
765         return DSL_DEV_MEI_ERR_SUCCESS;
766 }
767
768 /**
769  * Halt the ARC.
770  * This function halts the ARC.
771  *
772  * \param       pDev            the device pointer
773  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
774  * \ingroup     Internal
775  */
776 static DSL_DEV_MeiError_t
777 IFX_MEI_HaltArc (DSL_DEV_Device_t * pDev)
778 {
779         u32 arc_debug_data = 0x0;
780
781         //      Switch arc control from JTAG mode to MEI mode
782         IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
783         _IFX_MEI_DBGLongWordRead (pDev, MEI_DEBUG_DEC_AUX_MASK,
784                                         ARC_DEBUG, &arc_debug_data);
785         arc_debug_data |= ARC_DEBUG_HALT;
786         _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK,
787                                          ARC_DEBUG, arc_debug_data);
788         //      Switch arc control from MEI mode to JTAG mode
789         IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
790
791         MEI_WAIT (10);
792
793         return DSL_DEV_MEI_ERR_SUCCESS;
794 }
795
796 /**
797  * Run the ARC.
798  * This function runs the ARC.
799  *
800  * \param       pDev            the device pointer
801  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
802  * \ingroup     Internal
803  */
804 static DSL_DEV_MeiError_t
805 IFX_MEI_RunArc (DSL_DEV_Device_t * pDev)
806 {
807         u32 arc_debug_data = 0x0;
808
809         //      Switch arc control from JTAG mode to MEI mode- write '1' to bit0
810         IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
811         _IFX_MEI_DBGLongWordRead (pDev, MEI_DEBUG_DEC_AUX_MASK,
812                                         AUX_STATUS, &arc_debug_data);
813
814         //      Write debug data reg with content ANDd with 0xFDFFFFFF (halt bit cleared)
815         arc_debug_data &= ~ARC_AUX_HALT;
816         _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK,
817                                          AUX_STATUS, arc_debug_data);
818
819         //      Switch arc control from MEI mode to JTAG mode- write '0' to bit0
820         IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
821         //      Enable mask for arc codeswap interrupts
822         IFX_MEI_IRQEnable (pDev);
823
824         return DSL_DEV_MEI_ERR_SUCCESS;
825
826 }
827
828 /**
829  * Reset the ARC.
830  * This function resets the ARC.
831  *
832  * \param       pDev            the device pointer
833  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
834  * \ingroup     Internal
835  */
836 static DSL_DEV_MeiError_t
837 IFX_MEI_ResetARC (DSL_DEV_Device_t * pDev)
838 {
839         u32 arc_debug_data = 0;
840
841         IFX_MEI_HaltArc (pDev);
842
843         IFX_MEI_LongWordRead ((u32) IFXMIPS_RCU_RST, &arc_debug_data);
844         IFX_MEI_LongWordWrite ((u32) IFXMIPS_RCU_RST,
845                 arc_debug_data | IFXMIPS_RCU_RST_REQ_DFE | IFXMIPS_RCU_RST_REQ_AFE);
846
847         // reset ARC
848         IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_RST_CTRL, MEI_SOFT_RESET);
849         IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_RST_CTRL, 0);
850
851         IFX_MEI_IRQDisable (pDev);
852
853         IFX_MEI_EnableCLK (pDev);
854
855 #if 0
856         // reset part of PPE
857         *(unsigned long *) (BSP_PPE32_SRST) = 0xC30;
858         *(unsigned long *) (BSP_PPE32_SRST) = 0xFFF;
859 #endif
860
861         DSL_DEV_PRIVATE(pDev)->modem_ready = 0;
862
863         return DSL_DEV_MEI_ERR_SUCCESS;
864 }
865
866 DSL_DEV_MeiError_t
867 DSL_BSP_Showtime (DSL_DEV_Device_t * dev, DSL_uint32_t rate_fast, DSL_uint32_t rate_intl)
868 {
869     struct port_cell_info port_cell = {0};
870
871         IFX_MEI_EMSG ("Datarate US intl = %d, fast = %d\n", (int)rate_intl,
872                             (int)rate_fast);
873
874     if ( rate_fast )
875         g_tx_link_rate[0] = rate_fast / (53 * 8);
876     if ( rate_intl )
877         g_tx_link_rate[1] = rate_intl / (53 * 8);
878
879     if ( g_tx_link_rate[0] == 0 && g_tx_link_rate[1] == 0 ) {
880         IFX_MEI_EMSG ("Got rate fail.\n");
881     }
882
883         if ( ifx_mei_atm_showtime_enter )
884         {
885             port_cell.port_num = 2;
886             port_cell.tx_link_rate[0] = g_tx_link_rate[0];
887             port_cell.tx_link_rate[1] = g_tx_link_rate[1];
888         ifx_mei_atm_showtime_enter(&port_cell, g_xdata_addr);
889         }
890         else
891         {
892                 IFX_MEI_EMSG("no hookup from ATM driver to set cell rate\n");
893         }
894
895         return DSL_DEV_MEI_ERR_SUCCESS;
896 };
897
898 /**
899  * Reset/halt/run the DFE.
900  * This function provide operations to reset/halt/run the DFE.
901  *
902  * \param       pDev            the device pointer
903  * \param       mode            which operation want to do
904  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
905  * \ingroup     Internal
906  */
907 static DSL_DEV_MeiError_t
908 IFX_MEI_CpuModeSet (DSL_DEV_Device_t *pDev,
909                           DSL_DEV_CpuMode_t mode)
910 {
911         DSL_DEV_MeiError_t err_ret = DSL_DEV_MEI_ERR_FAILURE;
912         switch (mode) {
913         case DSL_CPU_HALT:
914                 err_ret = IFX_MEI_HaltArc (pDev);
915                 break;
916         case DSL_CPU_RUN:
917                 err_ret = IFX_MEI_RunArc (pDev);
918                 break;
919         case DSL_CPU_RESET:
920                 err_ret = IFX_MEI_ResetARC (pDev);
921                 break;
922         default:
923                 break;
924         }
925         return err_ret;
926 }
927
928 /**
929  * Accress DFE memory.
930  * This function provide a way to access DFE memory;
931  *
932  * \param       pDev            the device pointer
933  * \param       type            read or write
934  * \param       destaddr        destination address
935  * \param       databuff        pointer to hold data
936  * \param       databuffsize    size want to read/write
937  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
938  * \ingroup     Internal
939  */
940 DSL_DEV_MeiError_t
941 DSL_BSP_MemoryDebugAccess (DSL_DEV_Device_t * pDev,
942                                 DSL_BSP_MemoryAccessType_t type,
943                                 DSL_uint32_t destaddr, DSL_uint32_t *databuff,
944                                 DSL_uint32_t databuffsize)
945 {
946         DSL_DEV_MeiError_t meierr = DSL_DEV_MEI_ERR_SUCCESS;
947         switch (type) {
948         case DSL_BSP_MEMORY_READ:
949                 meierr = IFX_MEI_DebugRead (pDev, (u32)destaddr, (u32*)databuff, (u32)databuffsize);
950                 break;
951         case DSL_BSP_MEMORY_WRITE:
952                 meierr = IFX_MEI_DebugWrite (pDev, (u32)destaddr, (u32*)databuff, (u32)databuffsize);
953                 break;
954         }
955         return DSL_DEV_MEI_ERR_SUCCESS;
956 };
957
958 /**
959  * Download boot code to ARC.
960  * This function downloads boot code to ARC.
961  *
962  * \param       pDev            the device pointer
963  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
964  * \ingroup     Internal
965  */
966 static DSL_DEV_MeiError_t
967 IFX_MEI_DownloadBootCode (DSL_DEV_Device_t *pDev)
968 {
969         IFX_MEI_IRQDisable (pDev);
970
971         IFX_MEI_EnableCLK (pDev);
972
973         IFX_MEI_FuseProg (pDev);        //program fuse rar
974
975         IFX_MEI_DownloadBootPages (pDev);
976
977         return DSL_DEV_MEI_ERR_SUCCESS;
978 };
979
980 /**
981  * Enable Jtag debugger interface
982  * This function setups mips gpio to enable jtag debugger
983  *
984  * \param       pDev            the device pointer
985  * \param       enable          enable or disable
986  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
987  * \ingroup     Internal
988  */
989 static DSL_DEV_MeiError_t
990 IFX_MEI_ArcJtagEnable (DSL_DEV_Device_t *dev, int enable)
991 {
992         int meierr=0;
993         u32 reg_data;
994
995         switch (enable) {
996         case 1:
997                 //reserve gpio 9, 10, 11, 14, 19 for ARC JTAG
998                 ifxmips_port_reserve_pin (0, 9);
999                 ifxmips_port_reserve_pin (0, 10);
1000                 ifxmips_port_reserve_pin (0, 11);
1001                 ifxmips_port_reserve_pin (0, 14);
1002                 ifxmips_port_reserve_pin (1, 3);
1003
1004                 ifxmips_port_set_dir_in(0, 11);
1005                 ifxmips_port_clear_altsel0(0, 11);
1006                 ifxmips_port_clear_altsel1(0, 11);
1007                 ifxmips_port_set_open_drain(0, 11);
1008                 //enable ARC JTAG
1009                 IFX_MEI_LongWordRead ((u32) IFXMIPS_RCU_RST, &reg_data);
1010                 IFX_MEI_LongWordWrite ((u32) IFXMIPS_RCU_RST, reg_data | IFXMIPS_RCU_RST_REQ_ARC_JTAG);
1011                 break;
1012         case 0:
1013         default:
1014                 //reserve gpio 9, 10, 11, 14, 19 for ARC JTAG
1015                 meierr = ifxmips_port_free_pin (0, 9);
1016                 if (meierr < 0) {
1017                         IFX_MEI_EMSG ("Reserve GPIO 9 Fail.\n");
1018                         goto jtag_end;
1019                 }
1020                 meierr = ifxmips_port_free_pin (0, 10);
1021                 if (meierr < 0) {
1022                         IFX_MEI_EMSG ("Reserve GPIO 10 Fail.\n");
1023                         goto jtag_end;
1024                 }
1025                 meierr = ifxmips_port_free_pin (0, 11);
1026                 if (meierr < 0) {
1027                         IFX_MEI_EMSG ("Reserve GPIO 11 Fail.\n");
1028                         goto jtag_end;
1029                 }
1030                 meierr = ifxmips_port_free_pin (0, 14);
1031                 if (meierr < 0) {
1032                         IFX_MEI_EMSG ("Reserve GPIO 14 Fail.\n");
1033                         goto jtag_end;
1034                 }
1035                 meierr = ifxmips_port_free_pin (1, 3);
1036                 if (meierr < 0) {
1037                         IFX_MEI_EMSG ("Reserve GPIO 19 Fail.\n");
1038                         goto jtag_end;
1039                 }
1040                 break;
1041         }
1042 jtag_end:
1043         if (meierr)
1044                 return DSL_DEV_MEI_ERR_FAILURE;
1045
1046         return DSL_DEV_MEI_ERR_SUCCESS;
1047 };
1048
1049 /**
1050  * Enable DFE to MIPS interrupt
1051  * This function enable DFE to MIPS interrupt
1052  *
1053  * \param       pDev            the device pointer
1054  * \param       enable          enable or disable
1055  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
1056  * \ingroup     Internal
1057  */
1058 static DSL_DEV_MeiError_t
1059 IFX_MEI_AdslMailboxIRQEnable (DSL_DEV_Device_t *pDev, int enable)
1060 {
1061         DSL_DEV_MeiError_t meierr;
1062         switch (enable) {
1063         case 0:
1064                 meierr = DSL_DEV_MEI_ERR_SUCCESS;
1065                 IFX_MEI_IRQDisable (pDev);
1066                 break;
1067         case 1:
1068                 IFX_MEI_IRQEnable (pDev);
1069                 meierr = DSL_DEV_MEI_ERR_SUCCESS;
1070                 break;
1071         default:
1072                 meierr = DSL_DEV_MEI_ERR_FAILURE;
1073                 break;
1074
1075         }
1076         return meierr;
1077 }
1078
1079 /**
1080  * Get the modem status
1081  * This function return the modem status
1082  *
1083  * \param       pDev            the device pointer
1084  * \return      1: modem ready 0: not ready
1085  * \ingroup     Internal
1086  */
1087 static int
1088 IFX_MEI_IsModemReady (DSL_DEV_Device_t * pDev)
1089 {
1090         return DSL_DEV_PRIVATE(pDev)->modem_ready;
1091 }
1092
1093 DSL_DEV_MeiError_t
1094 DSL_BSP_AdslLedInit (DSL_DEV_Device_t * dev,
1095                           DSL_DEV_LedId_t led_number,
1096                           DSL_DEV_LedType_t type,
1097                           DSL_DEV_LedHandler_t handler)
1098 {
1099 #if 0
1100         struct led_config_param param;
1101         if (led_number == DSL_LED_LINK_ID && type == DSL_LED_LINK_TYPE && handler == /*DSL_LED_HD_CPU*/DSL_LED_HD_FW) {
1102                 param.operation_mask = CONFIG_OPERATION_UPDATE_SOURCE;
1103                 param.led = 0x01;
1104                 param.source = 0x01;
1105 //                bsp_led_config (&param);
1106
1107         } else if (led_number == DSL_LED_DATA_ID && type == DSL_LED_DATA_TYPE && (handler == DSL_LED_HD_FW)) {
1108                 param.operation_mask = CONFIG_OPERATION_UPDATE_SOURCE;
1109                 param.led = 0x02;
1110                 param.source = 0x02;
1111 //                bsp_led_config (&param);
1112         }
1113 #endif
1114         return DSL_DEV_MEI_ERR_SUCCESS;
1115 };
1116 #if 0
1117 DSL_DEV_MeiError_t
1118 DSL_BSP_AdslLedSet (DSL_DEV_Device_t * dev, DSL_DEV_LedId_t led_number, DSL_DEV_LedMode_t mode)
1119 {
1120         printk(KERN_INFO "[%s %d]: mode = %#x, led_number = %d\n", __func__, __LINE__, mode, led_number);
1121         switch (mode) {
1122         case DSL_LED_OFF:
1123                 switch (led_number) {
1124                 case DSL_LED_LINK_ID:
1125 #ifdef CONFIG_BSP_LED
1126                         bsp_led_set_blink (1, 0);
1127                         bsp_led_set_data (1, 0);
1128 #endif
1129                         break;
1130                 case DSL_LED_DATA_ID:
1131 #ifdef CONFIG_BSP_LED
1132                         bsp_led_set_blink (0, 0);
1133                         bsp_led_set_data (0, 0);
1134 #endif
1135                         break;
1136                 }
1137                 break;
1138         case DSL_LED_FLASH:
1139                 switch (led_number) {
1140                 case DSL_LED_LINK_ID:
1141 #ifdef CONFIG_BSP_LED
1142                         bsp_led_set_blink (1, 1);       // data
1143 #endif
1144                         break;
1145                 case DSL_LED_DATA_ID:
1146 #ifdef CONFIG_BSP_LED
1147                         bsp_led_set_blink (0, 1);       // data
1148 #endif
1149                         break;
1150                 }
1151                 break;
1152         case DSL_LED_ON:
1153                 switch (led_number) {
1154                 case DSL_LED_LINK_ID:
1155 #ifdef CONFIG_BSP_LED
1156                         bsp_led_set_blink (1, 0);
1157                         bsp_led_set_data (1, 1);
1158 #endif
1159                         break;
1160                 case DSL_LED_DATA_ID:
1161 #ifdef CONFIG_BSP_LED
1162                         bsp_led_set_blink (0, 0);
1163                         bsp_led_set_data (0, 1);
1164 #endif
1165                         break;
1166                 }
1167                 break;
1168         }
1169         return DSL_DEV_MEI_ERR_SUCCESS;
1170 };
1171
1172 #endif
1173
1174 /**
1175 * Compose a message.
1176 * This function compose a message from opcode, group, address, index, size, and data
1177 *
1178 * \param       opcode          The message opcode
1179 * \param       group           The message group number
1180 * \param       address         The message address.
1181 * \param       index           The message index.
1182 * \param       size            The number of words to read/write.
1183 * \param       data            The pointer to data.
1184 * \param       CMVMSG          The pointer to message buffer.
1185 * \ingroup     Internal
1186 */
1187 void
1188 makeCMV (u8 opcode, u8 group, u16 address, u16 index, int size, u16 * data, u16 *CMVMSG)
1189 {
1190         memset (CMVMSG, 0, MSG_LENGTH * 2);
1191         CMVMSG[0] = (opcode << 4) + (size & 0xf);
1192         CMVMSG[1] = (((index == 0) ? 0 : 1) << 7) + (group & 0x7f);
1193         CMVMSG[2] = address;
1194         CMVMSG[3] = index;
1195         if (opcode == H2D_CMV_WRITE)
1196                 memcpy (CMVMSG + 4, data, size * 2);
1197         return;
1198 }
1199
1200 /**
1201  * Send a message to ARC and read the response
1202  * This function sends a message to arc, waits the response, and reads the responses.
1203  *
1204  * \param       pDev            the device pointer
1205  * \param       request         Pointer to the request
1206  * \param       reply           Wait reply or not.
1207  * \param       response        Pointer to the response
1208  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
1209  * \ingroup     Internal
1210  */
1211 DSL_DEV_MeiError_t
1212 DSL_BSP_SendCMV (DSL_DEV_Device_t * pDev, u16 * request, int reply, u16 * response)     // write cmv to arc, if reply needed, wait for reply
1213 {
1214         DSL_DEV_MeiError_t meierror;
1215 #if defined(BSP_PORT_RTEMS)
1216         int delay_counter = 0;
1217 #endif
1218
1219         if (MEI_MUTEX_LOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema))
1220                 return -ERESTARTSYS;
1221
1222         DSL_DEV_PRIVATE(pDev)->cmv_reply = reply;
1223         memset (DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, 0,
1224                 sizeof (DSL_DEV_PRIVATE(pDev)->
1225                         CMV_RxMsg));
1226         DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
1227
1228         meierror = IFX_MEI_MailboxWrite (pDev, request, MSG_LENGTH);
1229
1230         if (meierror != DSL_DEV_MEI_ERR_SUCCESS) {
1231                 DSL_DEV_PRIVATE(pDev)->cmv_waiting = 0;
1232                 DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
1233                 IFX_MEI_EMSG ("MailboxWrite Fail!\n");
1234                 IFX_MEI_EMSG ("Resetting ARC...\n");
1235                 IFX_MEI_ResetARC(pDev);
1236                 MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
1237                 return meierror;
1238         }
1239         else {
1240                 DSL_DEV_PRIVATE(pDev)->cmv_count++;
1241         }
1242
1243         if (DSL_DEV_PRIVATE(pDev)->cmv_reply ==
1244             NO_REPLY) {
1245                 MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
1246                 return DSL_DEV_MEI_ERR_SUCCESS;
1247         }
1248
1249 #if !defined(BSP_PORT_RTEMS)
1250         if (DSL_DEV_PRIVATE(pDev)->arcmsgav == 0)
1251                 MEI_WAIT_EVENT_TIMEOUT (DSL_DEV_PRIVATE(pDev)->wait_queue_arcmsgav, CMV_TIMEOUT);
1252 #else
1253         while (DSL_DEV_PRIVATE(pDev)->arcmsgav == 0 && delay_counter < CMV_TIMEOUT / 5) {
1254                 MEI_WAIT (5);
1255                 delay_counter++;
1256         }
1257 #endif
1258
1259         DSL_DEV_PRIVATE(pDev)->cmv_waiting = 0;
1260         if (DSL_DEV_PRIVATE(pDev)->arcmsgav == 0) {     //CMV_timeout
1261                 DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
1262                 IFX_MEI_EMSG ("\%s: DSL_DEV_MEI_ERR_MAILBOX_TIMEOUT\n",
1263                                     __FUNCTION__);
1264                 MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
1265                 return DSL_DEV_MEI_ERR_MAILBOX_TIMEOUT;
1266         }
1267         else {
1268                 DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
1269                 DSL_DEV_PRIVATE(pDev)->
1270                         reply_count++;
1271                 memcpy (response, DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, MSG_LENGTH * 2);
1272                 MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
1273                 return DSL_DEV_MEI_ERR_SUCCESS;
1274         }
1275         MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
1276         return DSL_DEV_MEI_ERR_SUCCESS;
1277 }
1278
1279 /**
1280  * Reset the ARC, download boot codes, and run the ARC.
1281  * This function resets the ARC, downloads boot codes to ARC, and runs the ARC.
1282  *
1283  * \param       pDev            the device pointer
1284  * \return      DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
1285  * \ingroup     Internal
1286  */
1287 static DSL_DEV_MeiError_t
1288 IFX_MEI_RunAdslModem (DSL_DEV_Device_t *pDev)
1289 {
1290         int nSize = 0, idx = 0;
1291         uint32_t im0_register, im2_register;
1292 //      DSL_DEV_WinHost_Message_t m;
1293
1294         if (mei_arc_swap_buff == NULL) {
1295                 mei_arc_swap_buff =
1296                         (u32 *) kmalloc (MAXSWAPSIZE * 4, GFP_KERNEL);
1297                 if (mei_arc_swap_buff == NULL) {
1298                         IFX_MEI_EMSG (">>> malloc fail for codeswap buff!!! <<<\n");
1299                         return DSL_DEV_MEI_ERR_FAILURE;
1300                 }
1301                 printk("allocate %dKB swap buff memory at: 0x%p\n", ksize(mei_arc_swap_buff)/1024, mei_arc_swap_buff);
1302         }
1303
1304         DSL_DEV_PRIVATE(pDev)->img_hdr =
1305                 (ARC_IMG_HDR *) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[0].address;
1306         if ((DSL_DEV_PRIVATE(pDev)->img_hdr->
1307              count) * sizeof (ARC_SWP_PAGE_HDR) > SDRAM_SEGMENT_SIZE) {
1308                 IFX_MEI_EMSG ("firmware header size is bigger than 64K segment size\n");
1309                 return DSL_DEV_MEI_ERR_FAILURE;
1310         }
1311         // check image size
1312         for (idx = 0; idx < MAX_BAR_REGISTERS; idx++) {
1313                 nSize += DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].nCopy;
1314         }
1315         if (nSize !=
1316             DSL_DEV_PRIVATE(pDev)->image_size) {
1317                 IFX_MEI_EMSG ("Firmware download is not completed. Please download firmware again!\n");
1318                 return DSL_DEV_MEI_ERR_FAILURE;
1319         }
1320         // TODO: check crc
1321         ///
1322
1323         IFX_MEI_ResetARC (pDev);
1324         IFX_MEI_HaltArc (pDev);
1325         IFX_MEI_BarUpdate (pDev, DSL_DEV_PRIVATE(pDev)->nBar);
1326
1327         //IFX_MEI_DMSG("Starting to meiDownloadBootCode\n");
1328
1329         IFX_MEI_DownloadBootCode (pDev);
1330
1331         im0_register = (*IFXMIPS_ICU_IM0_IER) & (1 << 20);
1332         im2_register = (*IFXMIPS_ICU_IM2_IER) & (1 << 20);
1333         /* Turn off irq */
1334         #ifdef CONFIG_IFXMIPS_AMAZON_SE
1335         disable_irq (IFXMIPS_USB_OC_INT0);
1336         disable_irq (IFXMIPS_USB_OC_INT2);
1337         #elif defined(CONFIG_IFXMIPS_AR9)
1338         disable_irq (IFXMIPS_USB_OC_INT0);
1339         disable_irq (IFXMIPS_USB_OC_INT2);
1340         #elif defined(CONFIG_IFXMIPS_DANUBE)
1341         disable_irq (IFXMIPS_USB_OC_INT);
1342         #endif
1343         disable_irq (pDev->nIrq[IFX_DYING_GASP]);
1344
1345         IFX_MEI_RunArc (pDev);
1346
1347         MEI_WAIT_EVENT_TIMEOUT (DSL_DEV_PRIVATE(pDev)->wait_queue_modemready, 1000);
1348
1349         #ifdef CONFIG_IFXMIPS_AMAZON_SE
1350         MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT0);
1351         MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT2);
1352         #elif defined(CONFIG_IFXMIPS_AMAZON_S)
1353         MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT0);
1354         MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT2);
1355         #elif defined(CONFIG_IFXMIPS_DANUBE)
1356         MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT);
1357         #endif
1358         MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DYING_GASP]);
1359
1360         /* Re-enable irq */
1361         enable_irq(pDev->nIrq[IFX_DYING_GASP]);
1362         *IFXMIPS_ICU_IM0_IER |= im0_register;
1363         *IFXMIPS_ICU_IM2_IER |= im2_register;
1364
1365         if (DSL_DEV_PRIVATE(pDev)->modem_ready != 1) {
1366                 IFX_MEI_EMSG ("Modem failed to be ready!\n");
1367                 return DSL_DEV_MEI_ERR_FAILURE;
1368         } else {
1369                 IFX_MEI_DMSG("Modem is ready.\n");
1370                 return DSL_DEV_MEI_ERR_SUCCESS;
1371         }
1372 }
1373
1374 /**
1375  * Get the page's data pointer
1376  * This function caculats the data address from the firmware header.
1377  *
1378  * \param       pDev            the device pointer
1379  * \param       Page            The page number.
1380  * \param       data            Data page or program page.
1381  * \param       MaxSize         The maximum size to read.
1382  * \param       Buffer          Pointer to data.
1383  * \param       Dest            Pointer to the destination address.
1384  * \return      The number of bytes to read.
1385  * \ingroup     Internal
1386  */
1387 static int
1388 IFX_MEI_GetPage (DSL_DEV_Device_t * pDev, u32 Page, u32 data,
1389                        u32 MaxSize, u32 * Buffer, u32 * Dest)
1390 {
1391         u32 size;
1392         u32 i;
1393         u32 *p;
1394         u32 idx, offset, nBar = 0;
1395
1396         if (Page > DSL_DEV_PRIVATE(pDev)->img_hdr->count)
1397                 return -2;
1398         /*
1399          **     Get program or data size, depending on "data" flag
1400          */
1401         size = (data == GET_DATA) ? (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].d_size) :
1402                              (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].p_size);
1403         size &= BOOT_FLAG_MASK; //      Clear boot bit!
1404         if (size > MaxSize)
1405                 return -1;
1406
1407         if (size == 0)
1408                 return 0;
1409         /*
1410          **     Get program or data offset, depending on "data" flag
1411          */
1412         i = data ? (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].d_offset) :
1413                         (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].p_offset);
1414
1415         /*
1416          **     Copy data/program to buffer
1417          */
1418
1419         idx = i / SDRAM_SEGMENT_SIZE;
1420         offset = i % SDRAM_SEGMENT_SIZE;
1421         p = (u32 *) ((u8 *) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].address + offset);
1422
1423         for (i = 0; i < size; i++) {
1424                 if (offset + i * 4 - (nBar * SDRAM_SEGMENT_SIZE) >= SDRAM_SEGMENT_SIZE) {
1425                         idx++;
1426                         nBar++;
1427                         p = (u32 *) ((u8 *) KSEG1ADDR ((u32)DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].address));
1428                 }
1429                 Buffer[i] = *p++;
1430         }
1431
1432         /*
1433          **     Pass back data/program destination address
1434          */
1435         *Dest = data ? (DSL_DEV_PRIVATE(pDev)-> img_hdr->page[Page].d_dest) :
1436                                 (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].p_dest);
1437
1438         return size;
1439 }
1440
1441 /**
1442  * Free the memory for ARC firmware
1443  *
1444  * \param       pDev            the device pointer
1445  * \param       type    Free all memory or free the unused memory after showtime
1446  * \ingroup     Internal
1447  */
1448 const char *free_str[4] = {"Invalid", "Free_Reload", "Free_Showtime", "Free_All"};
1449 static int
1450 IFX_MEI_DFEMemoryFree (DSL_DEV_Device_t * pDev, int type)
1451 {
1452         int idx = 0;
1453         smmu_mem_info_t *adsl_mem_info =
1454                 DSL_DEV_PRIVATE(pDev)->adsl_mem_info;
1455
1456         for (idx = 0; idx < MAX_BAR_REGISTERS; idx++) {
1457                 if (type == FREE_ALL ||adsl_mem_info[idx].type == type) {
1458                         if (adsl_mem_info[idx].size > 0) {
1459                                 IFX_MEI_DMSG ("Freeing memory %p (%s)\n", adsl_mem_info[idx].org_address, free_str[adsl_mem_info[idx].type]);
1460                                 if ( idx == XDATA_REGISTER ) {
1461                                     g_xdata_addr = NULL;
1462                                     if ( ifx_mei_atm_showtime_exit )
1463                                         ifx_mei_atm_showtime_exit();
1464                                 }
1465                                 kfree (adsl_mem_info[idx].org_address);
1466                                 adsl_mem_info[idx].org_address = 0;
1467                                 adsl_mem_info[idx].address = 0;
1468                                 adsl_mem_info[idx].size = 0;
1469                                 adsl_mem_info[idx].type = 0;
1470                                 adsl_mem_info[idx].nCopy = 0;
1471                         }
1472                 }
1473         }
1474
1475         if(mei_arc_swap_buff != NULL){
1476                 printk("free %dKB swap buff memory at: 0x%p\n", ksize(mei_arc_swap_buff)/1024, mei_arc_swap_buff);
1477                 kfree(mei_arc_swap_buff);
1478                 mei_arc_swap_buff=NULL;
1479         }
1480
1481         return 0;
1482 }
1483 static int
1484 IFX_MEI_DFEMemoryAlloc (DSL_DEV_Device_t * pDev, long size)
1485 {
1486         unsigned long mem_ptr;
1487         char *org_mem_ptr = NULL;
1488         int idx = 0;
1489         long total_size = 0;
1490         int err = 0;
1491         smmu_mem_info_t *adsl_mem_info =
1492                 ((ifx_mei_device_private_t *) pDev->pPriv)->adsl_mem_info;
1493 //              DSL_DEV_PRIVATE(pDev)->adsl_mem_info;
1494         int allocate_size = SDRAM_SEGMENT_SIZE;
1495
1496         printk(KERN_INFO "[%s %d]: image_size = %ld\n", __func__, __LINE__, size);
1497         // Alloc Swap Pages
1498         for (idx = 0; size > 0 && idx < MAX_BAR_REGISTERS; idx++) {
1499                 // skip bar15 for XDATA usage.
1500 #ifndef CONFIG_IFXMIPS_MEI_FW_LOOPBACK
1501                 if (idx == XDATA_REGISTER)
1502                         continue;
1503 #endif
1504 #if 0
1505                 if (size < SDRAM_SEGMENT_SIZE) {
1506                         allocate_size = size;
1507                         if (allocate_size < 1024)
1508                                 allocate_size = 1024;
1509                 }
1510 #endif
1511                 if (idx == (MAX_BAR_REGISTERS - 1))
1512                         allocate_size = size;
1513                 else
1514                         allocate_size = SDRAM_SEGMENT_SIZE;
1515                 org_mem_ptr = kmalloc (allocate_size + 1024, GFP_KERNEL);
1516                 if (org_mem_ptr == NULL) {
1517                         IFX_MEI_EMSG ("%d: kmalloc %d bytes memory fail!\n", idx, allocate_size);
1518                         err = -ENOMEM;
1519                         goto allocate_error;
1520                 }
1521                 mem_ptr = (unsigned long) (org_mem_ptr + 1023) & ~(1024 -1);
1522                 adsl_mem_info[idx].address = (char *) mem_ptr;
1523                 adsl_mem_info[idx].org_address = org_mem_ptr;
1524                 adsl_mem_info[idx].size = allocate_size;
1525                 size -= allocate_size;
1526                 total_size += allocate_size;
1527         }
1528         if (size > 0) {
1529                 IFX_MEI_EMSG ("Image size is too large!\n");
1530                 err = -EFBIG;
1531                 goto allocate_error;
1532         }
1533         err = idx;
1534         return err;
1535
1536       allocate_error:
1537         IFX_MEI_DFEMemoryFree (pDev, FREE_ALL);
1538         return err;
1539 }
1540
1541 /**
1542  * Program the BAR registers
1543  *
1544  * \param       pDev            the device pointer
1545  * \param       nTotalBar       The number of bar to program.
1546  * \ingroup     Internal
1547  */
1548 static int
1549 IFX_MEI_BarUpdate (DSL_DEV_Device_t * pDev, int nTotalBar)
1550 {
1551         int idx = 0;
1552         smmu_mem_info_t *adsl_mem_info =
1553                 DSL_DEV_PRIVATE(pDev)->adsl_mem_info;
1554
1555         for (idx = 0; idx < nTotalBar; idx++) {
1556                 //skip XDATA register
1557                 if (idx == XDATA_REGISTER)
1558                         continue;
1559                 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XMEM_BAR_BASE + idx * 4,
1560                         (((uint32_t) adsl_mem_info[idx].address) & 0x0FFFFFFF));
1561         }
1562         for (idx = nTotalBar; idx < MAX_BAR_REGISTERS; idx++) {
1563                 if (idx == XDATA_REGISTER)
1564                         continue;
1565                 IFX_MEI_LongWordWriteOffset (pDev,  (u32) ME_XMEM_BAR_BASE  + idx * 4,
1566                          (((uint32_t)adsl_mem_info[nTotalBar - 1].address) & 0x0FFFFFFF));
1567                 /* These are for /proc/danube_mei/meminfo purpose */
1568                 adsl_mem_info[idx].address = adsl_mem_info[nTotalBar - 1].address;
1569                 adsl_mem_info[idx].org_address = adsl_mem_info[nTotalBar - 1].org_address;
1570                 adsl_mem_info[idx].size = 0; /* Prevent it from being freed */
1571         }
1572
1573     g_xdata_addr = adsl_mem_info[XDATA_REGISTER].address;
1574         IFX_MEI_LongWordWriteOffset (pDev,  (u32) ME_XMEM_BAR_BASE  + XDATA_REGISTER * 4,
1575                 (((uint32_t) adsl_mem_info [XDATA_REGISTER].address) & 0x0FFFFFFF));
1576         // update MEI_XDATA_BASE_SH
1577         IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XDATA_BASE_SH,
1578                  ((unsigned long)adsl_mem_info[XDATA_REGISTER].address) & 0x0FFFFFFF);
1579
1580         return DSL_DEV_MEI_ERR_SUCCESS;
1581 }
1582
1583 /* This copies the firmware from secondary storage to 64k memory segment in SDRAM */
1584 DSL_DEV_MeiError_t
1585 DSL_BSP_FWDownload (DSL_DEV_Device_t * pDev, const char *buf,
1586                          unsigned long size, long *loff, long *current_offset)
1587 {
1588         ARC_IMG_HDR img_hdr_tmp;
1589         smmu_mem_info_t *adsl_mem_info = DSL_DEV_PRIVATE(pDev)->adsl_mem_info;
1590
1591         size_t nRead = 0, nCopy = 0;
1592         char *mem_ptr;
1593         ssize_t retval = -ENOMEM;
1594         int idx = 0;
1595
1596         printk("\n%s\n", __func__);
1597
1598         if (*loff == 0) {
1599                 if (size < sizeof (img_hdr_tmp)) {
1600                         IFX_MEI_EMSG ("Firmware size is too small!\n");
1601                         return retval;
1602                 }
1603                 copy_from_user ((char *) &img_hdr_tmp, buf, sizeof (img_hdr_tmp));
1604                 // header of image_size and crc are not included.
1605                 DSL_DEV_PRIVATE(pDev)->image_size = le32_to_cpu (img_hdr_tmp.size) + 8;
1606
1607                 if (DSL_DEV_PRIVATE(pDev)->image_size > 1024 * 1024) {
1608                         IFX_MEI_EMSG ("Firmware size is too large!\n");
1609                         return retval;
1610                 }
1611                 // check if arc is halt
1612                 IFX_MEI_ResetARC (pDev);
1613                 IFX_MEI_HaltArc (pDev);
1614
1615                 IFX_MEI_DFEMemoryFree (pDev, FREE_ALL); //free all
1616
1617                 retval = IFX_MEI_DFEMemoryAlloc (pDev,  DSL_DEV_PRIVATE(pDev)->image_size);
1618                 if (retval < 0) {
1619                         IFX_MEI_EMSG ("Error: No memory space left.\n");
1620                         goto error;
1621                 }
1622                 for (idx = 0; idx < retval; idx++) {
1623                         //skip XDATA register
1624                         if (idx == XDATA_REGISTER)
1625                                 continue;
1626                         if (idx * SDRAM_SEGMENT_SIZE < le32_to_cpu (img_hdr_tmp.page[0].p_offset))
1627                                 adsl_mem_info[idx].type = FREE_RELOAD;
1628                         else
1629                                 adsl_mem_info[idx].type = FREE_SHOWTIME;
1630                 }
1631                 DSL_DEV_PRIVATE(pDev)->nBar = retval;
1632
1633                 DSL_DEV_PRIVATE(pDev)->img_hdr =
1634                         (ARC_IMG_HDR *) adsl_mem_info[0].address;
1635
1636                 adsl_mem_info[XDATA_REGISTER].org_address = kmalloc (SDRAM_SEGMENT_SIZE + 1024, GFP_KERNEL);
1637                 adsl_mem_info[XDATA_REGISTER].address =
1638                         (char *) ((unsigned long) (adsl_mem_info[XDATA_REGISTER].org_address + 1023) & 0xFFFFFC00);
1639
1640                 adsl_mem_info[XDATA_REGISTER].size = SDRAM_SEGMENT_SIZE;
1641
1642                 if (adsl_mem_info[XDATA_REGISTER].address == NULL) {
1643                         IFX_MEI_EMSG ("kmalloc memory fail!\n");
1644                         retval = -ENOMEM;
1645                         goto error;
1646                 }
1647                 adsl_mem_info[XDATA_REGISTER].type = FREE_RELOAD;
1648                 printk(KERN_INFO "[%s %d] -> IFX_MEI_BarUpdate()\n", __func__, __LINE__);
1649                 IFX_MEI_BarUpdate (pDev, (DSL_DEV_PRIVATE(pDev)->nBar));
1650         }
1651         else if (DSL_DEV_PRIVATE(pDev)-> image_size == 0) {
1652                 IFX_MEI_EMSG ("Error: Firmware size=0! \n");
1653                 goto error;
1654         }
1655
1656         nRead = 0;
1657         while (nRead < size) {
1658                 long offset = ((long) (*loff) + nRead) % SDRAM_SEGMENT_SIZE;
1659                 idx = (((long) (*loff)) + nRead) / SDRAM_SEGMENT_SIZE;
1660                 mem_ptr = (char *) KSEG1ADDR ((unsigned long) (adsl_mem_info[idx].address) + offset);
1661                 if ((size - nRead + offset) > SDRAM_SEGMENT_SIZE)
1662                         nCopy = SDRAM_SEGMENT_SIZE - offset;
1663                 else
1664                         nCopy = size - nRead;
1665                 copy_from_user (mem_ptr, buf + nRead, nCopy);
1666                 for (offset = 0; offset < (nCopy / 4); offset++) {
1667                         ((unsigned long *) mem_ptr)[offset] = le32_to_cpu (((unsigned long *) mem_ptr)[offset]);
1668                 }
1669                 nRead += nCopy;
1670                 adsl_mem_info[idx].nCopy += nCopy;
1671         }
1672
1673         *loff += size;
1674         *current_offset = size;
1675         return DSL_DEV_MEI_ERR_SUCCESS;
1676 error:
1677         IFX_MEI_DFEMemoryFree (pDev, FREE_ALL);
1678         return DSL_DEV_MEI_ERR_FAILURE;
1679 }
1680 /*
1681  * Register a callback event.
1682  * Return:
1683  * -1 if the event already has a callback function registered.
1684  *  0 success
1685  */
1686 int DSL_BSP_EventCBRegister(DSL_BSP_EventCallBack_t *p)
1687 {
1688         if (!p) {
1689                 IFX_MEI_EMSG("Invalid parameter!\n");
1690                 return -EINVAL;
1691         }
1692         if (p->event > DSL_BSP_CB_LAST || p->event < DSL_BSP_CB_FIRST) {
1693                 IFX_MEI_EMSG("Invalid Event %d\n", p->event);
1694                 return -EINVAL;
1695         }
1696         if (dsl_bsp_event_callback[p->event].function) {
1697                 IFX_MEI_EMSG("Event %d already has a callback function registered!\n", p->event);
1698                 return -1;
1699         } else {
1700                 dsl_bsp_event_callback[p->event].function = p->function;
1701                 dsl_bsp_event_callback[p->event].event    = p->event;
1702                 dsl_bsp_event_callback[p->event].pData    = p->pData;
1703         }
1704         return 0;
1705 }
1706 int DSL_BSP_EventCBUnregister(DSL_BSP_EventCallBack_t *p)
1707 {
1708         if (!p) {
1709                 IFX_MEI_EMSG("Invalid parameter!\n");
1710                 return -EINVAL;
1711         }
1712         if (p->event > DSL_BSP_CB_LAST || p->event < DSL_BSP_CB_FIRST) {
1713                 IFX_MEI_EMSG("Invalid Event %d\n", p->event);
1714                 return -EINVAL;
1715         }
1716         if (dsl_bsp_event_callback[p->event].function) {
1717                 IFX_MEI_EMSG("Unregistering Event %d...\n", p->event);
1718                 dsl_bsp_event_callback[p->event].function = NULL;
1719                 dsl_bsp_event_callback[p->event].pData    = NULL;
1720         } else {
1721                 IFX_MEI_EMSG("Event %d is not registered!\n", p->event);
1722                 return -1;
1723         }
1724         return 0;
1725 }
1726
1727 /**
1728  * MEI Dying Gasp interrupt handler
1729  *
1730  * \param int1
1731  * \param void0
1732  * \param regs  Pointer to the structure of danube mips registers
1733  * \ingroup     Internal
1734  */
1735 static irqreturn_t IFX_MEI_Dying_Gasp_IrqHandle (int int1, void *void0)
1736 {
1737         DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) void0;
1738         DSL_BSP_CB_Type_t event;
1739
1740         if (pDev == NULL)
1741                 IFX_MEI_EMSG("Error: Got Interrupt but pDev is NULL!!!!\n");
1742
1743 #ifndef CONFIG_SMP
1744         disable_irq (pDev->nIrq[IFX_DYING_GASP]);
1745 #else
1746         disable_irq_nosync(pDev->nIrq[IFX_DYING_GASP]);
1747 #endif
1748         event = DSL_BSP_CB_DYING_GASP;
1749
1750         if (dsl_bsp_event_callback[event].function)
1751                 (*dsl_bsp_event_callback[event].function)(pDev, event, dsl_bsp_event_callback[event].pData);
1752
1753 #ifdef CONFIG_USE_EMULATOR
1754     IFX_MEI_EMSG("Dying Gasp! Shutting Down... (Work around for Amazon-S Venus emulator)\n");
1755 #else
1756         IFX_MEI_EMSG("Dying Gasp! Shutting Down...\n");
1757 //      kill_proc (1, SIGINT, 1);       /* Ask init to reboot us */
1758 #endif
1759         return IRQ_HANDLED;
1760 }
1761
1762 extern void ifx_usb_enable_afe_oc(void);
1763
1764 /**
1765  * MEI interrupt handler
1766  *
1767  * \param int1
1768  * \param void0
1769  * \param regs  Pointer to the structure of danube mips registers
1770  * \ingroup     Internal
1771  */
1772 static irqreturn_t IFX_MEI_IrqHandle (int int1, void *void0)
1773 {
1774         u32 scratch;
1775         DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) void0;
1776 #if defined(CONFIG_IFXMIPS_MEI_FW_LOOPBACK) && defined(DFE_PING_TEST)
1777         dfe_loopback_irq_handler (pDev);
1778         return IRQ_HANDLED;
1779 #endif //CONFIG_AMAZON_S_MEI_FW_LOOPBACK
1780         DSL_BSP_CB_Type_t event;
1781
1782         if (pDev == NULL)
1783                 IFX_MEI_EMSG("Error: Got Interrupt but pDev is NULL!!!!\n");
1784
1785         IFX_MEI_DebugRead (pDev, ARC_MEI_MAILBOXR, &scratch, 1);
1786         if (scratch & OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK) {
1787                 IFX_MEI_EMSG("Receive Code Swap Request interrupt!!!\n");
1788                 return IRQ_HANDLED;
1789         }
1790         else if (scratch & OMB_CLEAREOC_INTERRUPT_CODE)  {
1791                 // clear eoc message interrupt
1792                 IFX_MEI_DMSG("OMB_CLEAREOC_INTERRUPT_CODE\n");
1793                 event = DSL_BSP_CB_CEOC_IRQ;
1794                 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_STAT, ARC_TO_MEI_MSGAV);
1795                 if (dsl_bsp_event_callback[event].function)
1796                         (*dsl_bsp_event_callback[event].function)(pDev, event, dsl_bsp_event_callback[event].pData);
1797         } else if (scratch & OMB_REBOOT_INTERRUPT_CODE) {
1798                 // Reboot
1799                 IFX_MEI_DMSG("OMB_REBOOT_INTERRUPT_CODE\n");
1800                 event = DSL_BSP_CB_FIRMWARE_REBOOT;
1801
1802                 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_STAT, ARC_TO_MEI_MSGAV);
1803
1804                 if (dsl_bsp_event_callback[event].function)
1805                         (*dsl_bsp_event_callback[event].function)(pDev, event, dsl_bsp_event_callback[event].pData);
1806         } else { // normal message
1807                 IFX_MEI_MailboxRead (pDev, DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, MSG_LENGTH);
1808                 if (DSL_DEV_PRIVATE(pDev)-> cmv_waiting == 1) {
1809                         DSL_DEV_PRIVATE(pDev)-> arcmsgav = 1;
1810                         DSL_DEV_PRIVATE(pDev)-> cmv_waiting = 0;
1811 #if !defined(BSP_PORT_RTEMS)
1812                         MEI_WAKEUP_EVENT (DSL_DEV_PRIVATE(pDev)->wait_queue_arcmsgav);
1813 #endif
1814                 }
1815                 else {
1816                         DSL_DEV_PRIVATE(pDev)-> modem_ready_cnt++;
1817                         memcpy ((char *) DSL_DEV_PRIVATE(pDev)->Recent_indicator,
1818                                 (char *) DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, MSG_LENGTH * 2);
1819                         if (((DSL_DEV_PRIVATE(pDev)->CMV_RxMsg[0] & 0xff0) >> 4) == D2H_AUTONOMOUS_MODEM_READY_MSG) {
1820                                 //check ARC ready message
1821                                 IFX_MEI_DMSG ("Got MODEM_READY_MSG\n");
1822                                 DSL_DEV_PRIVATE(pDev)->modem_ready = 1;
1823                                 MEI_WAKEUP_EVENT (DSL_DEV_PRIVATE(pDev)->wait_queue_modemready);
1824                         }
1825                 }
1826         }
1827
1828         return IRQ_HANDLED;
1829 }
1830
1831 int
1832 DSL_BSP_ATMLedCBRegister (int (*ifx_adsl_ledcallback) (void))
1833 {
1834     g_adsl_ledcallback = ifx_adsl_ledcallback;
1835     return 0;
1836 }
1837
1838 int
1839 DSL_BSP_ATMLedCBUnregister (int (*ifx_adsl_ledcallback) (void))
1840 {
1841     g_adsl_ledcallback = adsl_dummy_ledcallback;
1842     return 0;
1843 }
1844
1845 #if 0
1846 int
1847 DSL_BSP_EventCBRegister (int (*ifx_adsl_callback)
1848                                 (DSL_BSP_CB_Event_t * param))
1849 {
1850         int error = 0;
1851
1852         if (DSL_EventCB == NULL) {
1853                 DSL_EventCB = ifx_adsl_callback;
1854         }
1855         else {
1856                 error = -EIO;
1857         }
1858         return error;
1859 }
1860
1861 int
1862 DSL_BSP_EventCBUnregister (int (*ifx_adsl_callback)
1863                                   (DSL_BSP_CB_Event_t * param))
1864 {
1865         int error = 0;
1866
1867         if (DSL_EventCB == ifx_adsl_callback) {
1868                 DSL_EventCB = NULL;
1869         }
1870         else {
1871                 error = -EIO;
1872         }
1873         return error;
1874 }
1875
1876 static int
1877 DSL_BSP_GetEventCB (int (**ifx_adsl_callback)
1878                            (DSL_BSP_CB_Event_t * param))
1879 {
1880         *ifx_adsl_callback = DSL_EventCB;
1881         return 0;
1882 }
1883 #endif
1884
1885 #ifdef CONFIG_IFXMIPS_MEI_FW_LOOPBACK
1886 #define mte_reg_base    (0x4800*4+0x20000)
1887
1888 /* Iridia Registers Address Constants */
1889 #define MTE_Reg(r)      (int)(mte_reg_base + (r*4))
1890
1891 #define IT_AMODE        MTE_Reg(0x0004)
1892
1893 #define TIMER_DELAY     (1024)
1894 #define BC0_BYTES       (32)
1895 #define BC1_BYTES       (30)
1896 #define NUM_MB          (12)
1897 #define TIMEOUT_VALUE   2000
1898
1899 static void
1900 BFMWait (u32 cycle)
1901 {
1902         u32 i;
1903         for (i = 0; i < cycle; i++);
1904 }
1905
1906 static void
1907 WriteRegLong (u32 addr, u32 data)
1908 {
1909         //*((volatile u32 *)(addr)) =  data;
1910         IFX_MEI_WRITE_REGISTER_L (data, addr);
1911 }
1912
1913 static u32
1914 ReadRegLong (u32 addr)
1915 {
1916         // u32  rd_val;
1917         //rd_val = *((volatile u32 *)(addr));
1918         // return rd_val;
1919         return IFX_MEI_READ_REGISTER_L (addr);
1920 }
1921
1922 /* This routine writes the mailbox with the data in an input array */
1923 static void
1924 WriteMbox (u32 * mboxarray, u32 size)
1925 {
1926         IFX_MEI_DebugWrite (&dsl_devices[0], IMBOX_BASE, mboxarray, size);
1927         printk ("write to %X\n", IMBOX_BASE);
1928         IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_ME2ARC_INT, MEI_TO_ARC_MSGAV);
1929 }
1930
1931 /* This routine reads the output mailbox and places the results into an array */
1932 static void
1933 ReadMbox (u32 * mboxarray, u32 size)
1934 {
1935         IFX_MEI_DebugRead (&dsl_devices[0], OMBOX_BASE, mboxarray, size);
1936         printk ("read from %X\n", OMBOX_BASE);
1937 }
1938
1939 static void
1940 MEIWriteARCValue (u32 address, u32 value)
1941 {
1942         u32 i, check = 0;
1943
1944         /* Write address register */
1945         IFX_MEI_WRITE_REGISTER_L (address,  ME_DBG_WR_AD + IFXMIPS_MEI_BASE_ADDR);
1946
1947         /* Write data register */
1948         IFX_MEI_WRITE_REGISTER_L (value, ME_DBG_DATA + IFXMIPS_MEI_BASE_ADDR);
1949
1950         /* wait until complete - timeout at 40 */
1951         for (i = 0; i < 40; i++) {
1952                 check = IFX_MEI_READ_REGISTER_L (ME_ARC2ME_STAT + IFXMIPS_MEI_BASE_ADDR);
1953
1954                 if ((check & ARC_TO_MEI_DBG_DONE))
1955                         break;
1956         }
1957         /* clear the flag */
1958         IFX_MEI_WRITE_REGISTER_L (ARC_TO_MEI_DBG_DONE, ME_ARC2ME_STAT + IFXMIPS_MEI_BASE_ADDR);
1959 }
1960
1961 void
1962 arc_code_page_download (uint32_t arc_code_length, uint32_t * start_address)
1963 {
1964         int count;
1965
1966         printk ("try to download pages,size=%d\n", arc_code_length);
1967         IFX_MEI_ControlModeSet (&dsl_devices[0], MEI_MASTER_MODE);
1968         IFX_MEI_HaltArc (&dsl_devices[0]);
1969         IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_DX_AD, 0);
1970         for (count = 0; count < arc_code_length; count++) {
1971                 IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_DX_DATA,
1972                                                    *(start_address + count));
1973         }
1974         IFX_MEI_ControlModeSet (&dsl_devices[0], JTAG_MASTER_MODE);
1975 }
1976 static int
1977 load_jump_table (unsigned long addr)
1978 {
1979         int i;
1980         uint32_t addr_le, addr_be;
1981         uint32_t jump_table[32];
1982
1983         for (i = 0; i < 16; i++) {
1984                 addr_le = i * 8 + addr;
1985                 addr_be = ((addr_le >> 16) & 0xffff);
1986                 addr_be |= ((addr_le & 0xffff) << 16);
1987                 jump_table[i * 2 + 0] = 0x0f802020;
1988                 jump_table[i * 2 + 1] = addr_be;
1989                 //printk("jt %X %08X %08X\n",i,jump_table[i*2+0],jump_table[i*2+1]);
1990         }
1991         arc_code_page_download (32, &jump_table[0]);
1992 return 0;
1993 }
1994
1995 int got_int = 0;
1996
1997 void
1998 dfe_loopback_irq_handler (DSL_DEV_Device_t *pDev)
1999 {
2000         uint32_t rd_mbox[10];
2001
2002         memset (&rd_mbox[0], 0, 10 * 4);
2003         ReadMbox (&rd_mbox[0], 6);
2004         if (rd_mbox[0] == 0x0) {
2005                 printk ("Get ARC_ACK\n");
2006                 got_int = 1;
2007         }
2008         else if (rd_mbox[0] == 0x5) {
2009                 printk ("Get ARC_BUSY\n");
2010                 got_int = 2;
2011         }
2012         else if (rd_mbox[0] == 0x3) {
2013                 printk ("Get ARC_EDONE\n");
2014                 if (rd_mbox[1] == 0x0) {
2015                         got_int = 3;
2016                         printk ("Get E_MEMTEST\n");
2017                         if (rd_mbox[2] != 0x1) {
2018                                 got_int = 4;
2019                                 printk ("Get Result %X\n", rd_mbox[2]);
2020                         }
2021                 }
2022         }
2023         IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_ARC2ME_STAT,
2024                 ARC_TO_MEI_DBG_DONE);
2025         MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DFEIR]);
2026         disable_irq (pDev->nIrq[IFX_DFEIR]);
2027         //got_int = 1;
2028         return;
2029 }
2030
2031 static void
2032 wait_mem_test_result (void)
2033 {
2034         uint32_t mbox[5];
2035         mbox[0] = 0;
2036
2037         printk ("Waiting Starting\n");
2038         while (mbox[0] == 0) {
2039                 ReadMbox (&mbox[0], 5);
2040         }
2041         printk ("Try to get mem test result.\n");
2042         ReadMbox (&mbox[0], 5);
2043         if (mbox[0] == 0xA) {
2044                 printk ("Success.\n");
2045         }
2046         else if (mbox[0] == 0xA) {
2047                 printk ("Fail,address %X,except data %X,receive data %X\n",
2048                         mbox[1], mbox[2], mbox[3]);
2049         }
2050         else {
2051                 printk ("Fail\n");
2052         }
2053 }
2054
2055 static int
2056 arc_ping_testing (DSL_DEV_Device_t *pDev)
2057 {
2058 #define MEI_PING 0x00000001
2059         uint32_t wr_mbox[10], rd_mbox[10];
2060         int i;
2061
2062         for (i = 0; i < 10; i++) {
2063                 wr_mbox[i] = 0;
2064                 rd_mbox[i] = 0;
2065         }
2066
2067         printk ("send ping msg\n");
2068         wr_mbox[0] = MEI_PING;
2069         WriteMbox (&wr_mbox[0], 10);
2070
2071         while (got_int == 0) {
2072                 MEI_WAIT (100);
2073         }
2074
2075         printk ("send start event\n");
2076         got_int = 0;
2077
2078         wr_mbox[0] = 0x4;
2079         wr_mbox[1] = 0;
2080         wr_mbox[2] = 0;
2081         wr_mbox[3] = (uint32_t) 0xf5acc307e;
2082         wr_mbox[4] = 5;
2083         wr_mbox[5] = 2;
2084         wr_mbox[6] = 0x1c000;
2085         wr_mbox[7] = 64;
2086         wr_mbox[8] = 0;
2087         wr_mbox[9] = 0;
2088         WriteMbox (&wr_mbox[0], 10);
2089         DSL_ENABLE_IRQ (pDev->nIrq[IFX_DFEIR]);
2090         //printk("IFX_MEI_MailboxWrite ret=%d\n",i);
2091         IFX_MEI_LongWordWriteOffset (&dsl_devices[0],
2092                                            (u32) ME_ME2ARC_INT,
2093                                            MEI_TO_ARC_MSGAV);
2094         printk ("sleeping\n");
2095         while (1) {
2096                 if (got_int > 0) {
2097
2098                         if (got_int > 3)
2099                                 printk ("got_int >>>> 3\n");
2100                         else
2101                                 printk ("got int = %d\n", got_int);
2102                         got_int = 0;
2103                         //schedule();
2104                         DSL_ENABLE_IRQ (pDev->nIrq[IFX_DFEIR]);
2105                 }
2106                 //mbox_read(&rd_mbox[0],6);
2107                 MEI_WAIT (100);
2108         }
2109         return 0;
2110 }
2111
2112 static DSL_DEV_MeiError_t
2113 DFE_Loopback_Test (void)
2114 {
2115         int i = 0;
2116         u32 arc_debug_data = 0, temp;
2117         DSL_DEV_Device_t *pDev = &dsl_devices[0];
2118         uint32_t wr_mbox[10];
2119
2120         IFX_MEI_ResetARC (pDev);
2121         // start the clock
2122         arc_debug_data = ACL_CLK_MODE_ENABLE;
2123         IFX_MEI_DebugWrite (pDev, CRI_CCR0, &arc_debug_data, 1);
2124
2125 #if defined( DFE_PING_TEST )|| defined( DFE_ATM_LOOPBACK)
2126         // WriteARCreg(AUX_XMEM_LTEST,0);
2127         IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
2128 #define AUX_XMEM_LTEST 0x128
2129         _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK,  AUX_XMEM_LTEST, 0);
2130         IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
2131
2132         // WriteARCreg(AUX_XDMA_GAP,0);
2133         IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
2134 #define AUX_XDMA_GAP 0x114
2135         _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK, AUX_XDMA_GAP, 0);
2136         IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
2137
2138         IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
2139         temp = 0;
2140         _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK,
2141                 (u32) ME_XDATA_BASE_SH +  IFXMIPS_MEI_BASE_ADDR, temp);
2142         IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
2143
2144         i = IFX_MEI_DFEMemoryAlloc (pDev, SDRAM_SEGMENT_SIZE * 16);
2145         if (i >= 0) {
2146                 int idx;
2147
2148                 for (idx = 0; idx < i; idx++) {
2149                         DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].type = FREE_RELOAD;
2150                         IFX_MEI_WRITE_REGISTER_L ((((uint32_t) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].address) & 0x0fffffff),
2151                                                         IFXMIPS_MEI_BASE_ADDR + ME_XMEM_BAR_BASE  + idx * 4);
2152                         printk ("bar%d(%X)=%X\n", idx,
2153                                 IFXMIPS_MEI_BASE_ADDR + ME_XMEM_BAR_BASE  +
2154                                 idx * 4, (((uint32_t)
2155                                            ((ifx_mei_device_private_t *)
2156                                             pDev->pPriv)->adsl_mem_info[idx].
2157                                            address) & 0x0fffffff));
2158                         memset ((u8 *) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].address, 0, SDRAM_SEGMENT_SIZE);
2159                 }
2160
2161                 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XDATA_BASE_SH,
2162                                            ((unsigned long) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[XDATA_REGISTER].address) & 0x0FFFFFFF);
2163         }
2164         else {
2165                 IFX_MEI_EMSG ("cannot load image: no memory\n");
2166                 return DSL_DEV_MEI_ERR_FAILURE;
2167         }
2168         //WriteARCreg(AUX_IC_CTRL,2);
2169         printk(KERN_INFO "[%s %s %d]: Setting MEI_MASTER_MODE..\n", __FILE__, __func__, __LINE__);
2170         IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
2171 #define AUX_IC_CTRL 0x11
2172         _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK,
2173                                          AUX_IC_CTRL, 2);
2174         printk(KERN_INFO "[%s %s %d]: Setting JTAG_MASTER_MODE..\n", __FILE__, __func__, __LINE__);
2175         IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
2176
2177         printk(KERN_INFO "[%s %s %d]: Halting ARC...\n", __FILE__, __func__, __LINE__);
2178         IFX_MEI_HaltArc (&dsl_devices[0]);
2179
2180 #ifdef DFE_PING_TEST
2181
2182         printk ("ping test image size=%d\n", sizeof (arc_ahb_access_code));
2183         memcpy ((u8 *) (DSL_DEV_PRIVATE(pDev)->
2184                         adsl_mem_info[0].address + 0x1004),
2185                 &arc_ahb_access_code[0], sizeof (arc_ahb_access_code));
2186         load_jump_table (0x80000 + 0x1004);
2187
2188 #endif //DFE_PING_TEST
2189
2190         printk ("ARC ping test code download complete\n");
2191 #endif //defined( DFE_PING_TEST )|| defined( DFE_ATM_LOOPBACK)
2192 #ifdef DFE_MEM_TEST
2193         IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_ARC2ME_MASK, MSGAV_EN);
2194
2195         arc_code_page_download (1537, &code_array[0]);
2196         printk ("ARC mem test code download complete\n");
2197 #endif //DFE_MEM_TEST
2198 #ifdef DFE_ATM_LOOPBACK
2199         arc_debug_data = 0xf;
2200         arc_code_page_download (sizeof(code_array) / sizeof(*code_array), &code_array[0]);
2201         wr_mbox[0] = 0;     //TIMER_DELAY   - org: 1024
2202         wr_mbox[1] = 0;         //TXFB_START0
2203         wr_mbox[2] = 0x7f;      //TXFB_END0     - org: 49
2204         wr_mbox[3] = 0x80;      //TXFB_START1   - org: 80
2205         wr_mbox[4] = 0xff;      //TXFB_END1     - org: 109
2206         wr_mbox[5] = 0x100;     //RXFB_START0   - org: 0
2207         wr_mbox[6] = 0x17f;     //RXFB_END0     - org: 49
2208         wr_mbox[7] = 0x180;     //RXFB_START1   - org: 256
2209         wr_mbox[8] = 0x1ff;     //RXFB_END1     - org: 315
2210         WriteMbox (&wr_mbox[0], 9);
2211         // Start Iridia IT_AMODE (in dmp access) why is it required?
2212         IFX_MEI_DebugWrite (&dsl_devices[0], 0x32010, &arc_debug_data, 1);
2213 #endif //DFE_ATM_LOOPBACK
2214         IFX_MEI_IRQEnable (pDev);
2215         printk(KERN_INFO "[%s %s %d]: run ARC...\n", __FILE__, __func__, __LINE__);
2216         IFX_MEI_RunArc (&dsl_devices[0]);
2217
2218 #ifdef DFE_PING_TEST
2219         arc_ping_testing (pDev);
2220 #endif //DFE_PING_TEST
2221 #ifdef DFE_MEM_TEST
2222         wait_mem_test_result ();
2223 #endif //DFE_MEM_TEST
2224
2225         IFX_MEI_DFEMemoryFree (pDev, FREE_ALL);
2226         return DSL_DEV_MEI_ERR_SUCCESS;
2227 }
2228
2229 #endif //CONFIG_AMAZON_S_MEI_FW_LOOPBACK
2230
2231 static int
2232 IFX_MEI_InitDevNode (int num)
2233 {
2234         if (num == 0) {
2235                 if ((dev_major = register_chrdev (dev_major, IFX_MEI_DEVNAME, &bsp_mei_operations)) < 0) {
2236                         IFX_MEI_EMSG ("register_chrdev(%d %s) failed!\n", dev_major, IFX_MEI_DEVNAME);
2237                         return -ENODEV;
2238                 }
2239         }
2240         return 0;
2241 }
2242
2243 static int
2244 IFX_MEI_CleanUpDevNode (int num)
2245 {
2246         if (num == 0)
2247                 unregister_chrdev (dev_major, MEI_DIRNAME);
2248         return 0;
2249 }
2250
2251 static int
2252 IFX_MEI_InitDevice (int num)
2253 {
2254         DSL_DEV_Device_t *pDev;
2255         u32 temp;
2256         pDev = &dsl_devices[num];
2257         if (pDev == NULL)
2258                 return -ENOMEM;
2259         pDev->pPriv = &sDanube_Mei_Private[num];
2260         memset (pDev->pPriv, 0, sizeof (ifx_mei_device_private_t));
2261
2262         memset (&DSL_DEV_PRIVATE(pDev)->
2263                 adsl_mem_info[0], 0,
2264                 sizeof (smmu_mem_info_t) * MAX_BAR_REGISTERS);
2265
2266         if (num == 0) {
2267                 pDev->nIrq[IFX_DFEIR]      = IFXMIPS_MEI_INT;
2268                 pDev->nIrq[IFX_DYING_GASP] = IFXMIPS_MEI_DYING_GASP_INT;
2269                 pDev->base_address = IFXMIPS_MEI_BASE_ADDR;
2270
2271                 /* Power up MEI */
2272 #ifdef CONFIG_IFXMIPS_AMAZON_SE
2273                 *IFXMIPS_PMU_PWDCR &= ~(1 << 9);  // enable dsl
2274                 *IFXMIPS_PMU_PWDCR &= ~(1 << 15); // enable AHB base
2275 #else
2276                 temp = ifxmips_r32(IFXMIPS_PMU_PWDCR);
2277                 temp &= 0xffff7dbe;
2278                 ifxmips_w32(temp, IFXMIPS_PMU_PWDCR);
2279 #endif
2280         }
2281         pDev->nInUse = 0;
2282         DSL_DEV_PRIVATE(pDev)->modem_ready = 0;
2283         DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
2284
2285         MEI_INIT_WAKELIST ("arcq", DSL_DEV_PRIVATE(pDev)->wait_queue_arcmsgav); // for ARCMSGAV
2286         MEI_INIT_WAKELIST ("arcr", DSL_DEV_PRIVATE(pDev)->wait_queue_modemready);       // for arc modem ready
2287
2288         MEI_MUTEX_INIT (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema, 1);        // semaphore initialization, mutex
2289 #if 0
2290         MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DFEIR]);
2291         MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DYING_GASP]);
2292 #endif
2293         if (request_irq (pDev->nIrq[IFX_DFEIR], IFX_MEI_IrqHandle, 0, "DFEIR", pDev) != 0) {
2294                 IFX_MEI_EMSG ("request_irq %d failed!\n", pDev->nIrq[IFX_DFEIR]);
2295                 return -1;
2296         }
2297         if (request_irq (pDev->nIrq[IFX_DYING_GASP], IFX_MEI_Dying_Gasp_IrqHandle, 0, "DYING_GASP", pDev) != 0) {
2298                 IFX_MEI_EMSG ("request_irq %d failed!\n", pDev->nIrq[IFX_DYING_GASP]);
2299                 return -1;
2300         }
2301 //      IFX_MEI_DMSG("Device %d initialized. IER %#x\n", num, bsp_get_irq_ier(pDev->nIrq[IFX_DYING_GASP]));
2302         return 0;
2303 }
2304
2305 static int
2306 IFX_MEI_ExitDevice (int num)
2307 {
2308         DSL_DEV_Device_t *pDev;
2309         pDev = &dsl_devices[num];
2310
2311         if (pDev == NULL)
2312                 return -EIO;
2313
2314         disable_irq (pDev->nIrq[IFX_DFEIR]);
2315         disable_irq (pDev->nIrq[IFX_DYING_GASP]);
2316
2317         free_irq(pDev->nIrq[IFX_DFEIR], pDev);
2318         free_irq(pDev->nIrq[IFX_DYING_GASP], pDev);
2319
2320         return 0;
2321 }
2322
2323 static DSL_DEV_Device_t *
2324 IFX_BSP_HandleGet (int maj, int num)
2325 {
2326         if (num > BSP_MAX_DEVICES)
2327                 return NULL;
2328         return &dsl_devices[num];
2329 }
2330
2331 DSL_DEV_Device_t *
2332 DSL_BSP_DriverHandleGet (int maj, int num)
2333 {
2334         DSL_DEV_Device_t *pDev;
2335
2336         if (num > BSP_MAX_DEVICES)
2337                 return NULL;
2338
2339         pDev = &dsl_devices[num];
2340         if (!try_module_get(pDev->owner))
2341                 return NULL;
2342
2343         pDev->nInUse++;
2344         return pDev;
2345 }
2346
2347 int
2348 DSL_BSP_DriverHandleDelete (DSL_DEV_Device_t * nHandle)
2349 {
2350         DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) nHandle;
2351         if (pDev->nInUse)
2352                 pDev->nInUse--;
2353         module_put(pDev->owner);
2354         return 0;
2355 }
2356
2357 static int
2358 IFX_MEI_Open (DSL_DRV_inode_t * ino, DSL_DRV_file_t * fil)
2359 {
2360         int maj = MAJOR (ino->i_rdev);
2361         int num = MINOR (ino->i_rdev);
2362
2363         DSL_DEV_Device_t *pDev = NULL;
2364         if ((pDev = DSL_BSP_DriverHandleGet (maj, num)) == NULL) {
2365                 IFX_MEI_EMSG("open(%d:%d) fail!\n", maj, num);
2366                 return -EIO;
2367         }
2368         fil->private_data = pDev;
2369         return 0;
2370 }
2371
2372 static int
2373 IFX_MEI_Release (DSL_DRV_inode_t * ino, DSL_DRV_file_t * fil)
2374 {
2375         //int maj = MAJOR(ino->i_rdev);
2376         int num = MINOR (ino->i_rdev);
2377         DSL_DEV_Device_t *pDev;
2378
2379         pDev = &dsl_devices[num];
2380         if (pDev == NULL)
2381                 return -EIO;
2382         DSL_BSP_DriverHandleDelete (pDev);
2383         return 0;
2384 }
2385
2386 /**
2387  * Callback function for linux userspace program writing
2388  */
2389 static ssize_t
2390 IFX_MEI_Write (DSL_DRV_file_t * filp, const char *buf, size_t size, loff_t * loff)
2391 {
2392         DSL_DEV_MeiError_t mei_error = DSL_DEV_MEI_ERR_FAILURE;
2393         long offset = 0;
2394         DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) filp->private_data;
2395
2396         if (pDev == NULL)
2397                 return -EIO;
2398
2399         mei_error =
2400                 DSL_BSP_FWDownload (pDev, buf, size, (long *) loff,  &offset);
2401
2402         if (mei_error == DSL_DEV_MEI_ERR_FAILURE)
2403                 return -EIO;
2404         return (ssize_t) offset;
2405 }
2406
2407 /**
2408  * Callback function for linux userspace program ioctling
2409  */
2410 static int
2411 IFX_MEI_IoctlCopyFrom (int from_kernel, char *dest, char *from, int size)
2412 {
2413         int ret = 0;
2414
2415         if (!from_kernel)
2416                 ret = copy_from_user ((char *) dest, (char *) from, size);
2417         else
2418                 ret = (int)memcpy ((char *) dest, (char *) from, size);
2419         return ret;
2420 }
2421
2422 static int
2423 IFX_MEI_IoctlCopyTo (int from_kernel, char *dest, char *from, int size)
2424 {
2425         int ret = 0;
2426
2427         if (!from_kernel)
2428                 ret = copy_to_user ((char *) dest, (char *) from, size);
2429         else
2430                 ret = (int)memcpy ((char *) dest, (char *) from, size);
2431         return ret;
2432 }
2433
2434 static int
2435 IFX_MEI_Ioctls (DSL_DEV_Device_t * pDev, int from_kernel, unsigned int command, unsigned long lon)
2436 {
2437         int i = 0;
2438         int meierr = DSL_DEV_MEI_ERR_SUCCESS;
2439         u32 base_address = IFXMIPS_MEI_BASE_ADDR;
2440         DSL_DEV_WinHost_Message_t winhost_msg, m;
2441         DSL_DEV_MeiDebug_t debugrdwr;
2442         DSL_DEV_MeiReg_t regrdwr;
2443
2444         switch (command) {
2445
2446         case DSL_FIO_BSP_CMV_WINHOST:
2447                 IFX_MEI_IoctlCopyFrom (from_kernel, (char *) winhost_msg.msg.TxMessage,
2448                                              (char *) lon, MSG_LENGTH * 2);
2449
2450                 if ((meierr = DSL_BSP_SendCMV (pDev, winhost_msg.msg.TxMessage, YES_REPLY,
2451                                            winhost_msg.msg.RxMessage)) != DSL_DEV_MEI_ERR_SUCCESS) {
2452                         IFX_MEI_EMSG ("WINHOST CMV fail :TxMessage:%X %X %X %X, RxMessage:%X %X %X %X %X\n",
2453                                  winhost_msg.msg.TxMessage[0], winhost_msg.msg.TxMessage[1], winhost_msg.msg.TxMessage[2], winhost_msg.msg.TxMessage[3],
2454                                  winhost_msg.msg.RxMessage[0], winhost_msg.msg.RxMessage[1], winhost_msg.msg.RxMessage[2], winhost_msg.msg.RxMessage[3],
2455                                  winhost_msg.msg.RxMessage[4]);
2456                         meierr = DSL_DEV_MEI_ERR_FAILURE;
2457                 }
2458                 else {
2459                         IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
2460                                                    (char *) winhost_msg.msg.RxMessage,
2461                                                    MSG_LENGTH * 2);
2462                 }
2463                 break;
2464
2465         case DSL_FIO_BSP_CMV_READ:
2466                 IFX_MEI_IoctlCopyFrom (from_kernel, (char *) (&regrdwr),
2467                                              (char *) lon, sizeof (DSL_DEV_MeiReg_t));
2468
2469                 IFX_MEI_LongWordRead ((u32) regrdwr.iAddress,
2470                                             (u32 *) & (regrdwr.iData));
2471
2472                 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
2473                                            (char *) (&regrdwr),
2474                                            sizeof (DSL_DEV_MeiReg_t));
2475
2476                 break;
2477
2478         case DSL_FIO_BSP_CMV_WRITE:
2479                 IFX_MEI_IoctlCopyFrom (from_kernel, (char *) (&regrdwr),
2480                                              (char *) lon, sizeof (DSL_DEV_MeiReg_t));
2481
2482                 IFX_MEI_LongWordWrite ((u32) regrdwr.iAddress,
2483                                              regrdwr.iData);
2484                 break;
2485
2486         case DSL_FIO_BSP_GET_BASE_ADDRESS:
2487                 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
2488                                            (char *) (&base_address),
2489                                            sizeof (base_address));
2490                 break;
2491
2492         case DSL_FIO_BSP_IS_MODEM_READY:
2493                 i = IFX_MEI_IsModemReady (pDev);
2494                 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
2495                                            (char *) (&i), sizeof (int));
2496                 meierr = DSL_DEV_MEI_ERR_SUCCESS;
2497                 break;
2498         case DSL_FIO_BSP_RESET:
2499         case DSL_FIO_BSP_REBOOT:
2500                 meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_RESET);
2501                 meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_HALT);
2502                 break;
2503
2504         case DSL_FIO_BSP_HALT:
2505                 meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_HALT);
2506                 break;
2507
2508         case DSL_FIO_BSP_RUN:
2509                 meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_RUN);
2510                 break;
2511         case DSL_FIO_BSP_BOOTDOWNLOAD:
2512                 meierr = IFX_MEI_DownloadBootCode (pDev);
2513                 break;
2514         case DSL_FIO_BSP_JTAG_ENABLE:
2515                 meierr = IFX_MEI_ArcJtagEnable (pDev, 1);
2516                 break;
2517
2518         case DSL_FIO_BSP_REMOTE:
2519                 IFX_MEI_IoctlCopyFrom (from_kernel, (char *) (&i),
2520                                              (char *) lon, sizeof (int));
2521
2522                 meierr = IFX_MEI_AdslMailboxIRQEnable (pDev, i);
2523                 break;
2524
2525         case DSL_FIO_BSP_DSL_START:
2526                 printk("\n%s: DSL_FIO_BSP_DSL_START\n",__func__);
2527                 if ((meierr = IFX_MEI_RunAdslModem (pDev)) != DSL_DEV_MEI_ERR_SUCCESS) {
2528                         IFX_MEI_EMSG ("IFX_MEI_RunAdslModem() error...");
2529                         meierr = DSL_DEV_MEI_ERR_FAILURE;
2530                 }
2531                 break;
2532
2533         case DSL_FIO_BSP_DEBUG_READ:
2534         case DSL_FIO_BSP_DEBUG_WRITE:
2535                 IFX_MEI_IoctlCopyFrom (from_kernel,
2536                                              (char *) (&debugrdwr),
2537                                              (char *) lon,
2538                                              sizeof (debugrdwr));
2539
2540                 if (command == DSL_FIO_BSP_DEBUG_READ)
2541                         meierr = DSL_BSP_MemoryDebugAccess (pDev,
2542                                                                  DSL_BSP_MEMORY_READ,
2543                                                                  debugrdwr.
2544                                                                  iAddress,
2545                                                                  debugrdwr.
2546                                                                  buffer,
2547                                                                  debugrdwr.
2548                                                                  iCount);
2549                 else
2550                         meierr = DSL_BSP_MemoryDebugAccess (pDev,
2551                                                                  DSL_BSP_MEMORY_WRITE,
2552                                                                  debugrdwr.
2553                                                                  iAddress,
2554                                                                  debugrdwr.
2555                                                                  buffer,
2556                                                                  debugrdwr.
2557                                                                  iCount);
2558
2559                 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon, (char *) (&debugrdwr), sizeof (debugrdwr));
2560                 break;
2561         case DSL_FIO_BSP_GET_VERSION:
2562                 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon, (char *) (&bsp_mei_version), sizeof (DSL_DEV_Version_t));
2563                 break;
2564
2565         case DSL_FIO_BSP_GET_CHIP_INFO:
2566                 bsp_chip_info.major = 1;
2567                 bsp_chip_info.minor = IFXMIPS_MPS_CHIPID_VERSION_GET(*IFXMIPS_MPS_CHIPID);
2568                 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon, (char *) (&bsp_chip_info), sizeof (DSL_DEV_HwVersion_t));
2569                 meierr = DSL_DEV_MEI_ERR_SUCCESS;
2570                 break;
2571
2572         case DSL_FIO_BSP_FREE_RESOURCE:
2573                 makeCMV (H2D_CMV_READ, DSL_CMV_GROUP_STAT, 4, 0, 1, NULL, m.msg.TxMessage);
2574                 if (DSL_BSP_SendCMV (pDev, m.msg.TxMessage, YES_REPLY, m.msg.RxMessage) != DSL_DEV_MEI_ERR_SUCCESS) {
2575                         meierr = DSL_DEV_MEI_ERR_FAILURE;
2576                         return -EIO;
2577                 }
2578                 IFX_MEI_DMSG("RxMessage[4] = %#x\n", m.msg.RxMessage[4]);
2579                 if (!(m.msg.RxMessage[4] & DSL_DEV_STAT_CODESWAP_COMPLETE)) {
2580                         meierr = DSL_DEV_MEI_ERR_FAILURE;
2581                         return -EAGAIN;
2582                 }
2583                 IFX_MEI_DMSG("Freeing all memories marked FREE_SHOWTIME\n");
2584                 IFX_MEI_DFEMemoryFree (pDev, FREE_SHOWTIME);
2585                 meierr = DSL_DEV_MEI_ERR_SUCCESS;
2586                 break;
2587 #ifdef CONFIG_IFXMIPS_AMAZON_SE
2588         case DSL_FIO_ARC_MUX_TEST:
2589                 AMAZON_SE_MEI_ARC_MUX_Test();
2590                 break;
2591 #endif
2592         default:
2593 //              IFX_MEI_EMSG("Invalid IOCTL command: %d\n");
2594                 break;
2595         }
2596         return meierr;
2597 }
2598
2599 #ifdef CONFIG_IFXMIPS_AMAZON_SE
2600 void AMAZON_SE_MEI_ARC_MUX_Test(void)
2601 {
2602         u32 *p, i;
2603         *IFXMIPS_RCU_RST |= IFXMIPS_RCU_RST_REQ_MUX_ARC;
2604
2605         p = (u32*)(DFE_LDST_BASE_ADDR + IRAM0_BASE);
2606         IFX_MEI_EMSG("Writing to IRAM0(%p)...\n", p);
2607         for (i = 0; i < IRAM0_SIZE/sizeof(u32); i++, p++) {
2608                 *p = 0xdeadbeef;
2609                 if (*p != 0xdeadbeef)
2610                         IFX_MEI_EMSG("%p: %#x\n", p, *p);
2611         }
2612
2613         p = (u32*)(DFE_LDST_BASE_ADDR + IRAM1_BASE);
2614         IFX_MEI_EMSG("Writing to IRAM1(%p)...\n", p);
2615         for (i = 0; i < IRAM1_SIZE/sizeof(u32); i++, p++) {
2616                 *p = 0xdeadbeef;
2617                 if (*p != 0xdeadbeef)
2618                         IFX_MEI_EMSG("%p: %#x\n", p, *p);
2619         }
2620
2621         p = (u32*)(DFE_LDST_BASE_ADDR + BRAM_BASE);
2622         IFX_MEI_EMSG("Writing to BRAM(%p)...\n", p);
2623         for (i = 0; i < BRAM_SIZE/sizeof(u32); i++, p++) {
2624                 *p = 0xdeadbeef;
2625                 if (*p != 0xdeadbeef)
2626                         IFX_MEI_EMSG("%p: %#x\n", p, *p);
2627         }
2628
2629         p = (u32*)(DFE_LDST_BASE_ADDR + XRAM_BASE);
2630         IFX_MEI_EMSG("Writing to XRAM(%p)...\n", p);
2631         for (i = 0; i < XRAM_SIZE/sizeof(u32); i++, p++) {
2632                 *p = 0xdeadbeef;
2633                 if (*p != 0xdeadbeef)
2634                         IFX_MEI_EMSG("%p: %#x\n", p, *p);
2635         }
2636
2637         p = (u32*)(DFE_LDST_BASE_ADDR + YRAM_BASE);
2638         IFX_MEI_EMSG("Writing to YRAM(%p)...\n", p);
2639         for (i = 0; i < YRAM_SIZE/sizeof(u32); i++, p++) {
2640                 *p = 0xdeadbeef;
2641                 if (*p != 0xdeadbeef)
2642                         IFX_MEI_EMSG("%p: %#x\n", p, *p);
2643         }
2644
2645         p = (u32*)(DFE_LDST_BASE_ADDR + EXT_MEM_BASE);
2646         IFX_MEI_EMSG("Writing to EXT_MEM(%p)...\n", p);
2647         for (i = 0; i < EXT_MEM_SIZE/sizeof(u32); i++, p++) {
2648                 *p = 0xdeadbeef;
2649                 if (*p != 0xdeadbeef)
2650                         IFX_MEI_EMSG("%p: %#x\n", p, *p);
2651         }
2652         *IFXMIPS_RCU_RST &= ~IFXMIPS_RCU_RST_REQ_MUX_ARC;
2653 }
2654 #endif
2655 int
2656 DSL_BSP_KernelIoctls (DSL_DEV_Device_t * pDev, unsigned int command,
2657                            unsigned long lon)
2658 {
2659         int error = 0;
2660
2661         error = IFX_MEI_Ioctls (pDev, 1, command, lon);
2662         return error;
2663 }
2664
2665 static int
2666 IFX_MEI_UserIoctls (DSL_DRV_inode_t * ino, DSL_DRV_file_t * fil,
2667                           unsigned int command, unsigned long lon)
2668 {
2669         int error = 0;
2670         int maj = MAJOR (ino->i_rdev);
2671         int num = MINOR (ino->i_rdev);
2672         DSL_DEV_Device_t *pDev;
2673
2674         pDev = IFX_BSP_HandleGet (maj, num);
2675         if (pDev == NULL)
2676                 return -EIO;
2677
2678         error = IFX_MEI_Ioctls (pDev, 0, command, lon);
2679         return error;
2680 }
2681
2682 #ifdef CONFIG_PROC_FS
2683 /*
2684  * Register a callback function for linux proc filesystem
2685  */
2686 static int
2687 IFX_MEI_InitProcFS (int num)
2688 {
2689         struct proc_dir_entry *entry;
2690         int i ;
2691         DSL_DEV_Device_t *pDev;
2692         reg_entry_t regs_temp[PROC_ITEMS] = {
2693                 /* flag, name,      description } */
2694                 {NULL, "arcmsgav", "arc to mei message ", 0},
2695                 {NULL, "cmv_reply", "cmv needs reply", 0},
2696                 {NULL, "cmv_waiting", "waiting for cmv reply from arc", 0},
2697                 {NULL, "modem_ready_cnt", "ARC to MEI indicator count", 0},
2698                 {NULL, "cmv_count", "MEI to ARC CMVs", 0},
2699                 {NULL, "reply_count", "ARC to MEI Reply", 0},
2700                 {NULL, "Recent_indicator", "most recent indicator", 0},
2701                 {NULL, "fw_version", "Firmware Version", 0},
2702                 {NULL, "fw_date", "Firmware Date", 0},
2703                 {NULL, "meminfo", "Memory Allocation Information", 0},
2704                 {NULL, "version", "MEI version information", 0},
2705         };
2706
2707         pDev = &dsl_devices[num];
2708         if (pDev == NULL)
2709                 return -ENOMEM;
2710
2711         regs_temp[0].flag = &(DSL_DEV_PRIVATE(pDev)->arcmsgav);
2712         regs_temp[1].flag = &(DSL_DEV_PRIVATE(pDev)->cmv_reply);
2713         regs_temp[2].flag = &(DSL_DEV_PRIVATE(pDev)->cmv_waiting);
2714         regs_temp[3].flag = &(DSL_DEV_PRIVATE(pDev)->modem_ready_cnt);
2715         regs_temp[4].flag = &(DSL_DEV_PRIVATE(pDev)->cmv_count);
2716         regs_temp[5].flag = &(DSL_DEV_PRIVATE(pDev)->reply_count);
2717         regs_temp[6].flag = (int *) &(DSL_DEV_PRIVATE(pDev)->Recent_indicator);
2718
2719         memcpy ((char *) regs[num], (char *) regs_temp, sizeof (regs_temp));
2720         // procfs
2721         meidir = proc_mkdir (MEI_DIRNAME, NULL);
2722         if (meidir == NULL) {
2723                 IFX_MEI_EMSG ("Failed to create /proc/%s\n",  MEI_DIRNAME);
2724                 return (-ENOMEM);
2725         }
2726
2727         for (i = 0; i < NUM_OF_REG_ENTRY; i++) {
2728                 entry = create_proc_entry (regs[num][i].name,
2729                                            S_IWUSR | S_IRUSR | S_IRGRP |
2730                                            S_IROTH, meidir);
2731                 if (entry) {
2732                         regs[num][i].low_ino = entry->low_ino;
2733                         entry->proc_fops = &IFX_MEI_ProcOperations;
2734                 }
2735                 else {
2736                         IFX_MEI_EMSG ("Failed to create /proc/%s/%s\n", MEI_DIRNAME, regs[num][i].name);
2737                         return (-ENOMEM);
2738                 }
2739         }
2740         return 0;
2741 }
2742
2743 /*
2744  * Reading function for linux proc filesystem
2745  */
2746 static int
2747 IFX_MEI_ProcRead (struct file *file, char *buf, size_t nbytes, loff_t * ppos)
2748 {
2749         int i_ino = (file->f_dentry->d_inode)->i_ino;
2750         char *p = buf;
2751         int i;
2752         int num;
2753         reg_entry_t *entry = NULL;
2754         DSL_DEV_Device_t *pDev = NULL;
2755         DSL_DEV_WinHost_Message_t m;
2756
2757         for (num = 0; num < BSP_MAX_DEVICES; num++) {
2758                 for (i = 0; i < NUM_OF_REG_ENTRY; i++) {
2759                         if (regs[num][i].low_ino == (unsigned short)i_ino) {
2760                                 entry = &regs[num][i];
2761                                 pDev = &dsl_devices[num];
2762                                 break;
2763                         }
2764                 }
2765         }
2766         if (entry == NULL)
2767                 return -EINVAL;
2768         else if (strcmp(entry->name, "meminfo") == 0) {
2769                 if (*ppos > 0)  /* Assume reading completed in previous read */
2770                         return 0;
2771                 p += sprintf (p, "No           Address     Size\n");
2772                 for (i = 0; i < MAX_BAR_REGISTERS; i++) {
2773                         p += sprintf (p, "BAR[%02d] Addr:0x%08X Size:%lu\n",
2774                                           i, (u32) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[i].address,
2775                                           DSL_DEV_PRIVATE(pDev)-> adsl_mem_info[i].size);
2776                         //printk( "BAR[%02d] Addr:0x%08X Size:%d\n",i,adsl_mem_info[i].address,adsl_mem_info[i].size);
2777                 }
2778                 *ppos += (p - buf);
2779         } else if (strcmp(entry->name, "fw_version") == 0) {
2780                 if (*ppos > 0)  /* Assume reading completed in previous read */
2781                         return 0;
2782                 if (DSL_DEV_PRIVATE(pDev)->modem_ready_cnt < 1)
2783                         return -EAGAIN;
2784                 //major:bits 0-7
2785                 //minor:bits 8-15
2786                 makeCMV (H2D_CMV_READ, DSL_CMV_GROUP_INFO, 54, 0, 1, NULL, m.msg.TxMessage);
2787                 if (DSL_BSP_SendCMV (pDev, m.msg.TxMessage, YES_REPLY, m.msg.RxMessage) != DSL_DEV_MEI_ERR_SUCCESS)
2788                         return -EIO;
2789                 p += sprintf(p, "FW Version: %d.%d.", m.msg.RxMessage[4] & 0xFF, (m.msg.RxMessage[4] >> 8) & 0xFF);
2790                 //sub_version:bits 4-7
2791                 //int_version:bits 0-3
2792                 //spl_appl:bits 8-13
2793                 //rel_state:bits 14-15
2794                 makeCMV (H2D_CMV_READ, DSL_CMV_GROUP_INFO, 54, 1, 1, NULL, m.msg.TxMessage);
2795                 if (DSL_BSP_SendCMV (pDev, m.msg.TxMessage, YES_REPLY, m.msg.RxMessage) != DSL_DEV_MEI_ERR_SUCCESS)
2796                         return -EIO;
2797                 p += sprintf(p, "%d.%d.%d.%d\n",
2798                         (m.msg.RxMessage[4] >> 4) & 0xF, m.msg.RxMessage[4] & 0xF,
2799                         (m.msg.RxMessage[4] >> 14) & 3, (m.msg.RxMessage[4] >> 8) & 0x3F);
2800                 *ppos += (p - buf);
2801         } else if (strcmp(entry->name, "fw_date") == 0) {
2802                 if (*ppos > 0)  /* Assume reading completed in previous read */
2803                         return 0;
2804                 if (DSL_DEV_PRIVATE(pDev)->modem_ready_cnt < 1)
2805                         return -EAGAIN;
2806
2807                 makeCMV (H2D_CMV_READ, DSL_CMV_GROUP_INFO, 55, 0, 1, NULL, m.msg.TxMessage);
2808                 if (DSL_BSP_SendCMV (pDev, m.msg.TxMessage, YES_REPLY, m.msg.RxMessage) != DSL_DEV_MEI_ERR_SUCCESS)
2809                         return -EIO;
2810                 /* Day/Month */
2811                 p += sprintf(p, "FW Date: %d.%d.", m.msg.RxMessage[4] & 0xFF, (m.msg.RxMessage[4] >> 8) & 0xFF);
2812
2813                 makeCMV (H2D_CMV_READ, DSL_CMV_GROUP_INFO, 55, 2, 1, NULL, m.msg.TxMessage);
2814                 if (DSL_BSP_SendCMV (pDev, m.msg.TxMessage, YES_REPLY, m.msg.RxMessage) != DSL_DEV_MEI_ERR_SUCCESS)
2815                         return -EIO;
2816                 /* Year */
2817                 p += sprintf(p, "%d ", m.msg.RxMessage[4]);
2818
2819                 makeCMV (H2D_CMV_READ, DSL_CMV_GROUP_INFO, 55, 1, 1, NULL, m.msg.TxMessage);
2820                 if (DSL_BSP_SendCMV (pDev, m.msg.TxMessage, YES_REPLY, m.msg.RxMessage) != DSL_DEV_MEI_ERR_SUCCESS)
2821                         return -EIO;
2822                 /* Hour:Minute */
2823                 p += sprintf(p, "%d:%d\n", (m.msg.RxMessage[4] >> 8) & 0xFF, m.msg.RxMessage[4] & 0xFF);
2824
2825                 *ppos += (p - buf);
2826         } else if (strcmp(entry->name, "version") == 0) {
2827                 if (*ppos > 0)  /* Assume reading completed in previous read */
2828                         return 0;
2829                 p += sprintf (p, "IFX MEI V%ld.%ld.%ld\n", bsp_mei_version.major, bsp_mei_version.minor, bsp_mei_version.revision);
2830
2831                 *ppos += (p - buf);
2832         } else if (entry->flag != (int *) DSL_DEV_PRIVATE(pDev)->Recent_indicator) {
2833                 if (*ppos > 0)  /* Assume reading completed in previous read */
2834                         return 0;       // indicates end of file
2835                 p += sprintf (p, "0x%08X\n\n", *(entry->flag));
2836                 *ppos += (p - buf);
2837                 if ((p - buf) > nbytes) /* Assume output can be read at one time */
2838                         return -EINVAL;
2839         } else {
2840                 if ((int) (*ppos) / ((int) 7) == 16)
2841                         return 0;       // indicate end of the message
2842                 p += sprintf (p, "0x%04X\n\n", *(((u16 *) (entry->flag)) + (int) (*ppos) / ((int) 7)));
2843                 *ppos += (p - buf);
2844         }
2845         return p -  buf;
2846 }
2847
2848 /*
2849  * Writing function for linux proc filesystem
2850  */
2851 static ssize_t
2852 IFX_MEI_ProcWrite (struct file *file, const char *buffer, size_t count, loff_t * ppos)
2853 {
2854         int i_ino = (file->f_dentry->d_inode)->i_ino;
2855         reg_entry_t *current_reg = NULL;
2856         int i = 0;
2857         int num = 0;
2858         unsigned long newRegValue = 0;
2859         char *endp = NULL;
2860         DSL_DEV_Device_t *pDev = NULL;
2861
2862         for (num = 0; num < BSP_MAX_DEVICES; num++) {
2863                 for (i = 0; i < NUM_OF_REG_ENTRY; i++) {
2864                         if (regs[num][i].low_ino == i_ino) {
2865                                 current_reg = &regs[num][i];
2866                                 pDev = &dsl_devices[num];
2867                                 break;
2868                         }
2869                 }
2870         }
2871         if ((current_reg == NULL)
2872             || (current_reg->flag ==
2873                 (int *) DSL_DEV_PRIVATE(pDev)->
2874                 Recent_indicator))
2875                 return -EINVAL;
2876
2877         newRegValue = simple_strtoul (buffer, &endp, 0);
2878         *(current_reg->flag) = (int) newRegValue;
2879         return (count + endp - buffer);
2880 }
2881 #endif //CONFIG_PROC_FS
2882
2883 static int adsl_dummy_ledcallback(void)
2884 {
2885     return 0;
2886 }
2887
2888 int ifx_mei_atm_led_blink(void)
2889 {
2890     return g_adsl_ledcallback();
2891 }
2892 EXPORT_SYMBOL(ifx_mei_atm_led_blink);
2893
2894 int ifx_mei_atm_showtime_check(int *is_showtime, struct port_cell_info *port_cell, void **xdata_addr)
2895 {
2896     int i;
2897
2898     if ( is_showtime ) {
2899         *is_showtime = g_tx_link_rate[0] == 0 && g_tx_link_rate[1] == 0 ? 0 : 1;
2900     }
2901
2902     if ( port_cell ) {
2903         for ( i = 0; i < port_cell->port_num && i < 2; i++ )
2904             port_cell->tx_link_rate[i] = g_tx_link_rate[i];
2905     }
2906
2907     if ( xdata_addr ) {
2908         if ( g_tx_link_rate[0] == 0 && g_tx_link_rate[1] == 0 )
2909             *xdata_addr = NULL;
2910         else
2911             *xdata_addr = g_xdata_addr;
2912     }
2913
2914     return 0;
2915 }
2916 EXPORT_SYMBOL(ifx_mei_atm_showtime_check);
2917
2918 /*
2919  * Writing function for linux proc filesystem
2920  */
2921 int __init
2922 IFX_MEI_ModuleInit (void)
2923 {
2924         int i = 0;
2925
2926         printk ("IFX MEI Version %ld.%02ld.%02ld", bsp_mei_version.major, bsp_mei_version.minor, bsp_mei_version.revision);
2927
2928         for (i = 0; i < BSP_MAX_DEVICES; i++) {
2929                 if (IFX_MEI_InitDevice (i) != 0) {
2930                         printk ("%s: Init device fail!\n", __FUNCTION__);
2931                         return -EIO;
2932                 }
2933                 IFX_MEI_InitDevNode (i);
2934 #ifdef CONFIG_PROC_FS
2935                 IFX_MEI_InitProcFS (i);
2936 #endif
2937         }
2938         for (i = 0; i <= DSL_BSP_CB_LAST ; i++)
2939                 dsl_bsp_event_callback[i].function = NULL;
2940
2941 #ifdef CONFIG_IFXMIPS_MEI_FW_LOOPBACK
2942         printk(KERN_INFO "[%s %s %d]: Start loopback test...\n", __FILE__, __func__, __LINE__);
2943         DFE_Loopback_Test ();
2944 #endif
2945
2946         return 0;
2947 }
2948
2949 void __exit
2950 IFX_MEI_ModuleExit (void)
2951 {
2952         int i = 0;
2953         int num;
2954
2955         for (num = 0; num < BSP_MAX_DEVICES; num++) {
2956                 IFX_MEI_CleanUpDevNode (num);
2957 #ifdef CONFIG_PROC_FS
2958                 for (i = 0; i < NUM_OF_REG_ENTRY; i++) {
2959                         remove_proc_entry (regs[num][i].name, meidir);
2960                 }
2961 #endif
2962         }
2963
2964         remove_proc_entry (MEI_DIRNAME, NULL);
2965         for (i = 0; i < BSP_MAX_DEVICES; i++) {
2966                 for (i = 0; i < BSP_MAX_DEVICES; i++) {
2967                         IFX_MEI_ExitDevice (i);
2968                 }
2969         }
2970 }
2971
2972 /* export function for DSL Driver */
2973
2974 /* The functions of MEI_DriverHandleGet and MEI_DriverHandleDelete are
2975 something like open/close in kernel space , where the open could be used
2976 to register a callback for autonomous messages and returns a mei driver context pointer (comparable to the file descriptor in user space)
2977    The context will be required for the multi line chips future! */
2978
2979 EXPORT_SYMBOL (DSL_BSP_DriverHandleGet);
2980 EXPORT_SYMBOL (DSL_BSP_DriverHandleDelete);
2981
2982 EXPORT_SYMBOL (DSL_BSP_ATMLedCBRegister);
2983 EXPORT_SYMBOL (DSL_BSP_ATMLedCBUnregister);
2984 EXPORT_SYMBOL (DSL_BSP_KernelIoctls);
2985 EXPORT_SYMBOL (DSL_BSP_AdslLedInit);
2986 //EXPORT_SYMBOL (DSL_BSP_AdslLedSet);
2987 EXPORT_SYMBOL (DSL_BSP_FWDownload);
2988 EXPORT_SYMBOL (DSL_BSP_Showtime);
2989
2990 EXPORT_SYMBOL (DSL_BSP_MemoryDebugAccess);
2991 EXPORT_SYMBOL (DSL_BSP_SendCMV);
2992
2993 // provide a register/unregister function for DSL driver to register a event callback function
2994 EXPORT_SYMBOL (DSL_BSP_EventCBRegister);
2995 EXPORT_SYMBOL (DSL_BSP_EventCBUnregister);
2996
2997 module_init (IFX_MEI_ModuleInit);
2998 module_exit (IFX_MEI_ModuleExit);