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