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