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