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