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