Root/package/platform/lantiq/ltq-adsl-mei/src/lantiq_mei.c

1/******************************************************************************
2
3                               Copyright (c) 2009
4                            Infineon Technologies AG
5                     Am Campeon 1-12; 81726 Munich, Germany
6
7  For licensing information, see the file 'LICENSE' in the root folder of
8  this software module.
9
10******************************************************************************/
11
12/*!
13  \defgroup AMAZON_S_MEI Amazon-S MEI Driver Module
14  \brief Amazon-S MEI driver module
15 */
16
17/*!
18  \defgroup Internal Compile Parametere
19  \ingroup AMAZON_S_MEI
20  \brief exported functions for other driver use
21 */
22
23/*!
24  \file amazon_s_mei_bsp.c
25  \ingroup AMAZON_S_MEI
26  \brief Amazon-S MEI driver file
27 */
28
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/version.h>
32#include <generated/utsrelease.h>
33#include <linux/types.h>
34#include <linux/fs.h>
35#include <linux/mm.h>
36#include <linux/errno.h>
37#include <linux/interrupt.h>
38#include <linux/netdevice.h>
39#include <linux/etherdevice.h>
40#include <linux/proc_fs.h>
41#include <linux/init.h>
42#include <linux/ioport.h>
43#include <linux/delay.h>
44#include <linux/device.h>
45#include <linux/sched.h>
46#include <linux/platform_device.h>
47#include <asm/uaccess.h>
48#include <asm/hardirq.h>
49
50#include "lantiq_atm.h"
51#include <lantiq_soc.h>
52//#include "ifxmips_atm.h"
53#define IFX_MEI_BSP
54#include "ifxmips_mei_interface.h"
55
56/*#define LTQ_RCU_RST IFX_RCU_RST_REQ
57#define LTQ_RCU_RST_REQ_ARC_JTAG IFX_RCU_RST_REQ_ARC_JTAG
58#define LTQ_RCU_RST_REQ_DFE IFX_RCU_RST_REQ_DFE
59#define LTQ_RCU_RST_REQ_AFE IFX_RCU_RST_REQ_AFE
60#define IFXMIPS_FUSE_BASE_ADDR IFX_FUSE_BASE_ADDR
61#define IFXMIPS_ICU_IM0_IER IFX_ICU_IM0_IER
62#define IFXMIPS_ICU_IM2_IER IFX_ICU_IM2_IER
63#define LTQ_MEI_INT IFX_MEI_INT
64#define LTQ_MEI_DYING_GASP_INT IFX_MEI_DYING_GASP_INT
65#define LTQ_MEI_BASE_ADDR IFX_MEI_SPACE_ACCESS
66#define IFXMIPS_PMU_PWDCR IFX_PMU_PWDCR
67#define IFXMIPS_MPS_CHIPID IFX_MPS_CHIPID
68
69#define ifxmips_port_reserve_pin ifx_gpio_pin_reserve
70#define ifxmips_port_set_dir_in ifx_gpio_dir_in_set
71#define ifxmips_port_clear_altsel0 ifx_gpio_altsel0_set
72#define ifxmips_port_clear_altsel1 ifx_gpio_altsel1_clear
73#define ifxmips_port_set_open_drain ifx_gpio_open_drain_clear
74#define ifxmips_port_free_pin ifx_gpio_pin_free
75#define ifxmips_mask_and_ack_irq bsp_mask_and_ack_irq
76#define IFXMIPS_MPS_CHIPID_VERSION_GET IFX_MCD_CHIPID_VERSION_GET
77#define ltq_r32(reg) __raw_readl(reg)
78#define ltq_w32(val, reg) __raw_writel(val, reg)
79#define ltq_w32_mask(clear, set, reg) ltq_w32((ltq_r32(reg) & ~clear) | set, reg)
80*/
81
82#define LTQ_RCU_BASE_ADDR 0x1F203000
83#define LTQ_ICU_BASE_ADDR 0x1F880200
84#define LTQ_MEI_BASE_ADDR 0x1E116000
85#define LTQ_PMU_BASE_ADDR 0x1F102000
86#define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21)
87#define LTQ_USB_OC_INT (INT_NUM_IM4_IRL0 + 23)
88#define LTQ_MEI_INT (INT_NUM_IM1_IRL0 + 23)
89
90#define LTQ_RCU_RST_REQ_DFE (1 << 7)
91#define LTQ_RCU_RST_REQ_AFE (1 << 11)
92
93#define LTQ_PMU_BASE (KSEG1 + LTQ_PMU_BASE_ADDR)
94#define LTQ_RCU_BASE (KSEG1 + LTQ_RCU_BASE_ADDR)
95#define LTQ_ICU_BASE (KSEG1 + LTQ_ICU_BASE_ADDR)
96
97#define LTQ_PMU_PWDCR ((u32 *)(LTQ_PMU_BASE + 0x001C))
98#define LTQ_PMU_PWDSR ((u32 *)(LTQ_PMU_BASE + 0x0020))
99#define LTQ_RCU_RST ((u32 *)(LTQ_RCU_BASE + 0x0010))
100#define LTQ_RCU_RST_ALL 0x40000000
101
102#define LTQ_ICU_IM0_ISR ((u32 *)(LTQ_ICU_BASE + 0x0000))
103#define LTQ_ICU_IM0_IER ((u32 *)(LTQ_ICU_BASE + 0x0008))
104#define LTQ_ICU_IM0_IOSR ((u32 *)(LTQ_ICU_BASE + 0x0010))
105#define LTQ_ICU_IM0_IRSR ((u32 *)(LTQ_ICU_BASE + 0x0018))
106#define LTQ_ICU_IM0_IMR ((u32 *)(LTQ_ICU_BASE + 0x0020))
107
108
109#define LTQ_ICU_IM1_ISR ((u32 *)(LTQ_ICU_BASE + 0x0028))
110#define LTQ_ICU_IM2_ISR ((u32 *)(LTQ_ICU_BASE + 0x0050))
111#define LTQ_ICU_IM3_ISR ((u32 *)(LTQ_ICU_BASE + 0x0078))
112#define LTQ_ICU_IM4_ISR ((u32 *)(LTQ_ICU_BASE + 0x00A0))
113
114#define LTQ_ICU_OFFSET (LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR)
115#define LTQ_ICU_IM2_IER (LTQ_ICU_IM0_IER + LTQ_ICU_OFFSET)
116
117#define IFX_MEI_EMSG(fmt, args...) pr_err("[%s %d]: " fmt,__FUNCTION__, __LINE__, ## args)
118#define IFX_MEI_DMSG(fmt, args...) pr_debug("[%s %d]: " fmt,__FUNCTION__, __LINE__, ## args)
119
120#define LTQ_FUSE_BASE (KSEG1 + 0x1F107354)
121
122#ifdef CONFIG_LTQ_MEI_FW_LOOPBACK
123//#define DFE_MEM_TEST
124//#define DFE_PING_TEST
125#define DFE_ATM_LOOPBACK
126
127
128#ifdef DFE_ATM_LOOPBACK
129#include <asm/ifxmips/ifxmips_mei_fw_loopback.h>
130#endif
131
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        org_mem_ptr = kmalloc (allocate_size + 1024, GFP_KERNEL);
1517        if (org_mem_ptr == NULL) {
1518                        IFX_MEI_EMSG ("%d: kmalloc %d bytes memory fail!\n", idx, allocate_size);
1519            err = -ENOMEM;
1520            goto allocate_error;
1521        }
1522                mem_ptr = (unsigned long) (org_mem_ptr + 1023) & ~(1024 -1);
1523                adsl_mem_info[idx].address = (char *) mem_ptr;
1524                adsl_mem_info[idx].org_address = org_mem_ptr;
1525                adsl_mem_info[idx].size = allocate_size;
1526                size -= allocate_size;
1527                total_size += allocate_size;
1528    }
1529    if (size > 0) {
1530        IFX_MEI_EMSG ("Image size is too large!\n");
1531        err = -EFBIG;
1532        goto allocate_error;
1533    }
1534    err = idx;
1535    return err;
1536
1537      allocate_error:
1538    IFX_MEI_DFEMemoryFree (pDev, FREE_ALL);
1539    return err;
1540}
1541
1542/**
1543 * Program the BAR registers
1544 *
1545 * \param pDev the device pointer
1546 * \param nTotalBar The number of bar to program.
1547 * \ingroup Internal
1548 */
1549static int
1550IFX_MEI_BarUpdate (DSL_DEV_Device_t * pDev, int nTotalBar)
1551{
1552    int idx = 0;
1553    smmu_mem_info_t *adsl_mem_info =
1554        DSL_DEV_PRIVATE(pDev)->adsl_mem_info;
1555
1556    for (idx = 0; idx < nTotalBar; idx++) {
1557        //skip XDATA register
1558        if (idx == XDATA_REGISTER)
1559            continue;
1560        IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XMEM_BAR_BASE + idx * 4,
1561            (((uint32_t) adsl_mem_info[idx].address) & 0x0FFFFFFF));
1562    }
1563    for (idx = nTotalBar; idx < MAX_BAR_REGISTERS; idx++) {
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[nTotalBar - 1].address) & 0x0FFFFFFF));
1568        /* These are for /proc/danube_mei/meminfo purpose */
1569        adsl_mem_info[idx].address = adsl_mem_info[nTotalBar - 1].address;
1570        adsl_mem_info[idx].org_address = adsl_mem_info[nTotalBar - 1].org_address;
1571        adsl_mem_info[idx].size = 0; /* Prevent it from being freed */
1572    }
1573
1574    g_xdata_addr = adsl_mem_info[XDATA_REGISTER].address;
1575    IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XMEM_BAR_BASE + XDATA_REGISTER * 4,
1576        (((uint32_t) adsl_mem_info [XDATA_REGISTER].address) & 0x0FFFFFFF));
1577    // update MEI_XDATA_BASE_SH
1578    IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XDATA_BASE_SH,
1579         ((unsigned long)adsl_mem_info[XDATA_REGISTER].address) & 0x0FFFFFFF);
1580
1581    return DSL_DEV_MEI_ERR_SUCCESS;
1582}
1583
1584/* This copies the firmware from secondary storage to 64k memory segment in SDRAM */
1585DSL_DEV_MeiError_t
1586DSL_BSP_FWDownload (DSL_DEV_Device_t * pDev, const char *buf,
1587             unsigned long size, long *loff, long *current_offset)
1588{
1589    ARC_IMG_HDR img_hdr_tmp;
1590    smmu_mem_info_t *adsl_mem_info = DSL_DEV_PRIVATE(pDev)->adsl_mem_info;
1591
1592    size_t nRead = 0, nCopy = 0;
1593    char *mem_ptr;
1594    ssize_t retval = -ENOMEM;
1595    int idx = 0;
1596
1597        IFX_MEI_DMSG("\n");
1598
1599    if (*loff == 0) {
1600        if (size < sizeof (img_hdr_tmp)) {
1601            IFX_MEI_EMSG ("Firmware size is too small!\n");
1602            return retval;
1603        }
1604        copy_from_user ((char *) &img_hdr_tmp, buf, sizeof (img_hdr_tmp));
1605        // header of image_size and crc are not included.
1606        DSL_DEV_PRIVATE(pDev)->image_size = le32_to_cpu (img_hdr_tmp.size) + 8;
1607
1608        if (DSL_DEV_PRIVATE(pDev)->image_size > 1024 * 1024) {
1609            IFX_MEI_EMSG ("Firmware size is too large!\n");
1610            return retval;
1611        }
1612        // check if arc is halt
1613        IFX_MEI_ResetARC (pDev);
1614        IFX_MEI_HaltArc (pDev);
1615
1616        IFX_MEI_DFEMemoryFree (pDev, FREE_ALL); //free all
1617
1618        retval = IFX_MEI_DFEMemoryAlloc (pDev, DSL_DEV_PRIVATE(pDev)->image_size);
1619        if (retval < 0) {
1620            IFX_MEI_EMSG ("Error: No memory space left.\n");
1621            goto error;
1622        }
1623        for (idx = 0; idx < retval; idx++) {
1624            //skip XDATA register
1625            if (idx == XDATA_REGISTER)
1626                continue;
1627            if (idx * SDRAM_SEGMENT_SIZE < le32_to_cpu (img_hdr_tmp.page[0].p_offset))
1628                adsl_mem_info[idx].type = FREE_RELOAD;
1629            else
1630                adsl_mem_info[idx].type = FREE_SHOWTIME;
1631        }
1632        DSL_DEV_PRIVATE(pDev)->nBar = retval;
1633
1634        DSL_DEV_PRIVATE(pDev)->img_hdr =
1635            (ARC_IMG_HDR *) adsl_mem_info[0].address;
1636
1637        adsl_mem_info[XDATA_REGISTER].org_address = kmalloc (SDRAM_SEGMENT_SIZE + 1024, GFP_KERNEL);
1638        adsl_mem_info[XDATA_REGISTER].address =
1639            (char *) ((unsigned long) (adsl_mem_info[XDATA_REGISTER].org_address + 1023) & 0xFFFFFC00);
1640
1641        adsl_mem_info[XDATA_REGISTER].size = SDRAM_SEGMENT_SIZE;
1642
1643        if (adsl_mem_info[XDATA_REGISTER].address == NULL) {
1644            IFX_MEI_EMSG ("kmalloc memory fail!\n");
1645            retval = -ENOMEM;
1646            goto error;
1647        }
1648        adsl_mem_info[XDATA_REGISTER].type = FREE_RELOAD;
1649        IFX_MEI_DMSG("-> IFX_MEI_BarUpdate()\n");
1650        IFX_MEI_BarUpdate (pDev, (DSL_DEV_PRIVATE(pDev)->nBar));
1651    }
1652    else if (DSL_DEV_PRIVATE(pDev)-> image_size == 0) {
1653        IFX_MEI_EMSG ("Error: Firmware size=0! \n");
1654        goto error;
1655    }
1656
1657    nRead = 0;
1658    while (nRead < size) {
1659        long offset = ((long) (*loff) + nRead) % SDRAM_SEGMENT_SIZE;
1660        idx = (((long) (*loff)) + nRead) / SDRAM_SEGMENT_SIZE;
1661        mem_ptr = (char *) KSEG1ADDR ((unsigned long) (adsl_mem_info[idx].address) + offset);
1662        if ((size - nRead + offset) > SDRAM_SEGMENT_SIZE)
1663            nCopy = SDRAM_SEGMENT_SIZE - offset;
1664        else
1665            nCopy = size - nRead;
1666        copy_from_user (mem_ptr, buf + nRead, nCopy);
1667        for (offset = 0; offset < (nCopy / 4); offset++) {
1668            ((unsigned long *) mem_ptr)[offset] = le32_to_cpu (((unsigned long *) mem_ptr)[offset]);
1669        }
1670        nRead += nCopy;
1671        adsl_mem_info[idx].nCopy += nCopy;
1672    }
1673
1674    *loff += size;
1675    *current_offset = size;
1676    return DSL_DEV_MEI_ERR_SUCCESS;
1677error:
1678    IFX_MEI_DFEMemoryFree (pDev, FREE_ALL);
1679    return DSL_DEV_MEI_ERR_FAILURE;
1680}
1681/*
1682 * Register a callback event.
1683 * Return:
1684 * -1 if the event already has a callback function registered.
1685 * 0 success
1686 */
1687int DSL_BSP_EventCBRegister(DSL_BSP_EventCallBack_t *p)
1688{
1689    if (!p) {
1690                IFX_MEI_EMSG("Invalid parameter!\n");
1691                return -EINVAL;
1692    }
1693        if (p->event > DSL_BSP_CB_LAST || p->event < DSL_BSP_CB_FIRST) {
1694                IFX_MEI_EMSG("Invalid Event %d\n", p->event);
1695                return -EINVAL;
1696        }
1697        if (dsl_bsp_event_callback[p->event].function) {
1698                IFX_MEI_EMSG("Event %d already has a callback function registered!\n", p->event);
1699                return -1;
1700        } else {
1701                dsl_bsp_event_callback[p->event].function = p->function;
1702                dsl_bsp_event_callback[p->event].event = p->event;
1703                dsl_bsp_event_callback[p->event].pData = p->pData;
1704        }
1705        return 0;
1706}
1707int DSL_BSP_EventCBUnregister(DSL_BSP_EventCallBack_t *p)
1708{
1709    if (!p) {
1710                IFX_MEI_EMSG("Invalid parameter!\n");
1711                return -EINVAL;
1712    }
1713        if (p->event > DSL_BSP_CB_LAST || p->event < DSL_BSP_CB_FIRST) {
1714                IFX_MEI_EMSG("Invalid Event %d\n", p->event);
1715                return -EINVAL;
1716        }
1717        if (dsl_bsp_event_callback[p->event].function) {
1718                IFX_MEI_EMSG("Unregistering Event %d...\n", p->event);
1719                dsl_bsp_event_callback[p->event].function = NULL;
1720                dsl_bsp_event_callback[p->event].pData = NULL;
1721        } else {
1722                IFX_MEI_EMSG("Event %d is not registered!\n", p->event);
1723                return -1;
1724        }
1725        return 0;
1726}
1727
1728/**
1729 * MEI Dying Gasp interrupt handler
1730 *
1731 * \param int1
1732 * \param void0
1733 * \param regs Pointer to the structure of danube mips registers
1734 * \ingroup Internal
1735 */
1736/*static irqreturn_t IFX_MEI_Dying_Gasp_IrqHandle (int int1, void *void0)
1737{
1738    DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) void0;
1739        DSL_BSP_CB_Type_t event;
1740
1741    if (pDev == NULL)
1742        IFX_MEI_EMSG("Error: Got Interrupt but pDev is NULL!!!!\n");
1743
1744#ifndef CONFIG_SMP
1745    disable_irq (pDev->nIrq[IFX_DYING_GASP]);
1746#else
1747    disable_irq_nosync(pDev->nIrq[IFX_DYING_GASP]);
1748#endif
1749    event = DSL_BSP_CB_DYING_GASP;
1750
1751    if (dsl_bsp_event_callback[event].function)
1752        (*dsl_bsp_event_callback[event].function)(pDev, event, dsl_bsp_event_callback[event].pData);
1753
1754#ifdef CONFIG_USE_EMULATOR
1755    IFX_MEI_EMSG("Dying Gasp! Shutting Down... (Work around for Amazon-S Venus emulator)\n");
1756#else
1757    IFX_MEI_EMSG("Dying Gasp! Shutting Down...\n");
1758// kill_proc (1, SIGINT, 1);
1759#endif
1760        return IRQ_HANDLED;
1761}
1762*/
1763extern void ifx_usb_enable_afe_oc(void);
1764
1765/**
1766 * MEI interrupt handler
1767 *
1768 * \param int1
1769 * \param void0
1770 * \param regs Pointer to the structure of danube mips registers
1771 * \ingroup Internal
1772 */
1773static irqreturn_t IFX_MEI_IrqHandle (int int1, void *void0)
1774{
1775    u32 scratch;
1776    DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) void0;
1777#if defined(CONFIG_LTQ_MEI_FW_LOOPBACK) && defined(DFE_PING_TEST)
1778    dfe_loopback_irq_handler (pDev);
1779    return IRQ_HANDLED;
1780#endif //CONFIG_AMAZON_S_MEI_FW_LOOPBACK
1781        DSL_BSP_CB_Type_t event;
1782
1783    if (pDev == NULL)
1784        IFX_MEI_EMSG("Error: Got Interrupt but pDev is NULL!!!!\n");
1785
1786    IFX_MEI_DebugRead (pDev, ARC_MEI_MAILBOXR, &scratch, 1);
1787    if (scratch & OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK) {
1788        IFX_MEI_EMSG("Receive Code Swap Request interrupt!!!\n");
1789        return IRQ_HANDLED;
1790    }
1791    else if (scratch & OMB_CLEAREOC_INTERRUPT_CODE) {
1792        // clear eoc message interrupt
1793        IFX_MEI_DMSG("OMB_CLEAREOC_INTERRUPT_CODE\n");
1794                event = DSL_BSP_CB_CEOC_IRQ;
1795        IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_STAT, ARC_TO_MEI_MSGAV);
1796                if (dsl_bsp_event_callback[event].function)
1797            (*dsl_bsp_event_callback[event].function)(pDev, event, dsl_bsp_event_callback[event].pData);
1798        } else if (scratch & OMB_REBOOT_INTERRUPT_CODE) {
1799                // Reboot
1800                IFX_MEI_DMSG("OMB_REBOOT_INTERRUPT_CODE\n");
1801                event = DSL_BSP_CB_FIRMWARE_REBOOT;
1802
1803        IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_STAT, ARC_TO_MEI_MSGAV);
1804
1805                if (dsl_bsp_event_callback[event].function)
1806                        (*dsl_bsp_event_callback[event].function)(pDev, event, dsl_bsp_event_callback[event].pData);
1807        } else { // normal message
1808                IFX_MEI_MailboxRead (pDev, DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, MSG_LENGTH);
1809                if (DSL_DEV_PRIVATE(pDev)-> cmv_waiting == 1) {
1810                        DSL_DEV_PRIVATE(pDev)-> arcmsgav = 1;
1811                        DSL_DEV_PRIVATE(pDev)-> cmv_waiting = 0;
1812#if !defined(BSP_PORT_RTEMS)
1813                        MEI_WAKEUP_EVENT (DSL_DEV_PRIVATE(pDev)->wait_queue_arcmsgav);
1814#endif
1815                }
1816        else {
1817            DSL_DEV_PRIVATE(pDev)-> modem_ready_cnt++;
1818            memcpy ((char *) DSL_DEV_PRIVATE(pDev)->Recent_indicator,
1819                (char *) DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, MSG_LENGTH * 2);
1820            if (((DSL_DEV_PRIVATE(pDev)->CMV_RxMsg[0] & 0xff0) >> 4) == D2H_AUTONOMOUS_MODEM_READY_MSG) {
1821                //check ARC ready message
1822                IFX_MEI_DMSG ("Got MODEM_READY_MSG\n");
1823                DSL_DEV_PRIVATE(pDev)->modem_ready = 1;
1824                MEI_WAKEUP_EVENT (DSL_DEV_PRIVATE(pDev)->wait_queue_modemready);
1825            }
1826        }
1827    }
1828
1829    return IRQ_HANDLED;
1830}
1831
1832int
1833DSL_BSP_ATMLedCBRegister (int (*ifx_adsl_ledcallback) (void))
1834{
1835    g_adsl_ledcallback = ifx_adsl_ledcallback;
1836    return 0;
1837}
1838
1839int
1840DSL_BSP_ATMLedCBUnregister (int (*ifx_adsl_ledcallback) (void))
1841{
1842    g_adsl_ledcallback = adsl_dummy_ledcallback;
1843    return 0;
1844}
1845
1846#if 0
1847int
1848DSL_BSP_EventCBRegister (int (*ifx_adsl_callback)
1849                    (DSL_BSP_CB_Event_t * param))
1850{
1851    int error = 0;
1852
1853    if (DSL_EventCB == NULL) {
1854        DSL_EventCB = ifx_adsl_callback;
1855    }
1856    else {
1857        error = -EIO;
1858    }
1859    return error;
1860}
1861
1862int
1863DSL_BSP_EventCBUnregister (int (*ifx_adsl_callback)
1864                  (DSL_BSP_CB_Event_t * param))
1865{
1866    int error = 0;
1867
1868    if (DSL_EventCB == ifx_adsl_callback) {
1869        DSL_EventCB = NULL;
1870    }
1871    else {
1872        error = -EIO;
1873    }
1874    return error;
1875}
1876
1877static int
1878DSL_BSP_GetEventCB (int (**ifx_adsl_callback)
1879               (DSL_BSP_CB_Event_t * param))
1880{
1881    *ifx_adsl_callback = DSL_EventCB;
1882    return 0;
1883}
1884#endif
1885
1886#ifdef CONFIG_LTQ_MEI_FW_LOOPBACK
1887#define mte_reg_base (0x4800*4+0x20000)
1888
1889/* Iridia Registers Address Constants */
1890#define MTE_Reg(r) (int)(mte_reg_base + (r*4))
1891
1892#define IT_AMODE MTE_Reg(0x0004)
1893
1894#define TIMER_DELAY (1024)
1895#define BC0_BYTES (32)
1896#define BC1_BYTES (30)
1897#define NUM_MB (12)
1898#define TIMEOUT_VALUE 2000
1899
1900static void
1901BFMWait (u32 cycle)
1902{
1903    u32 i;
1904    for (i = 0; i < cycle; i++);
1905}
1906
1907static void
1908WriteRegLong (u32 addr, u32 data)
1909{
1910    //*((volatile u32 *)(addr)) = data;
1911    IFX_MEI_WRITE_REGISTER_L (data, addr);
1912}
1913
1914static u32
1915ReadRegLong (u32 addr)
1916{
1917    // u32 rd_val;
1918    //rd_val = *((volatile u32 *)(addr));
1919    // return rd_val;
1920    return IFX_MEI_READ_REGISTER_L (addr);
1921}
1922
1923/* This routine writes the mailbox with the data in an input array */
1924static void
1925WriteMbox (u32 * mboxarray, u32 size)
1926{
1927    IFX_MEI_DebugWrite (&dsl_devices[0], IMBOX_BASE, mboxarray, size);
1928    IFX_MEI_DMSG("write to %X\n", IMBOX_BASE);
1929    IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_ME2ARC_INT, MEI_TO_ARC_MSGAV);
1930}
1931
1932/* This routine reads the output mailbox and places the results into an array */
1933static void
1934ReadMbox (u32 * mboxarray, u32 size)
1935{
1936    IFX_MEI_DebugRead (&dsl_devices[0], OMBOX_BASE, mboxarray, size);
1937    IFX_MEI_DMSG("read from %X\n", OMBOX_BASE);
1938}
1939
1940static void
1941MEIWriteARCValue (u32 address, u32 value)
1942{
1943    u32 i, check = 0;
1944
1945    /* Write address register */
1946    IFX_MEI_WRITE_REGISTER_L (address, ME_DBG_WR_AD + LTQ_MEI_BASE_ADDR);
1947
1948    /* Write data register */
1949    IFX_MEI_WRITE_REGISTER_L (value, ME_DBG_DATA + LTQ_MEI_BASE_ADDR);
1950
1951    /* wait until complete - timeout at 40 */
1952    for (i = 0; i < 40; i++) {
1953        check = IFX_MEI_READ_REGISTER_L (ME_ARC2ME_STAT + LTQ_MEI_BASE_ADDR);
1954
1955        if ((check & ARC_TO_MEI_DBG_DONE))
1956            break;
1957    }
1958    /* clear the flag */
1959    IFX_MEI_WRITE_REGISTER_L (ARC_TO_MEI_DBG_DONE, ME_ARC2ME_STAT + LTQ_MEI_BASE_ADDR);
1960}
1961
1962void
1963arc_code_page_download (uint32_t arc_code_length, uint32_t * start_address)
1964{
1965    int count;
1966
1967    IFX_MEI_DMSG("try to download pages,size=%d\n", arc_code_length);
1968    IFX_MEI_ControlModeSet (&dsl_devices[0], MEI_MASTER_MODE);
1969    IFX_MEI_HaltArc (&dsl_devices[0]);
1970    IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_DX_AD, 0);
1971    for (count = 0; count < arc_code_length; count++) {
1972        IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_DX_DATA,
1973                           *(start_address + count));
1974    }
1975    IFX_MEI_ControlModeSet (&dsl_devices[0], JTAG_MASTER_MODE);
1976}
1977static int
1978load_jump_table (unsigned long addr)
1979{
1980    int i;
1981    uint32_t addr_le, addr_be;
1982    uint32_t jump_table[32];
1983
1984    for (i = 0; i < 16; i++) {
1985        addr_le = i * 8 + addr;
1986        addr_be = ((addr_le >> 16) & 0xffff);
1987        addr_be |= ((addr_le & 0xffff) << 16);
1988        jump_table[i * 2 + 0] = 0x0f802020;
1989        jump_table[i * 2 + 1] = addr_be;
1990        //printk("jt %X %08X %08X\n",i,jump_table[i*2+0],jump_table[i*2+1]);
1991    }
1992    arc_code_page_download (32, &jump_table[0]);
1993return 0;
1994}
1995
1996int got_int = 0;
1997
1998void
1999dfe_loopback_irq_handler (DSL_DEV_Device_t *pDev)
2000{
2001    uint32_t rd_mbox[10];
2002
2003    memset (&rd_mbox[0], 0, 10 * 4);
2004    ReadMbox (&rd_mbox[0], 6);
2005    if (rd_mbox[0] == 0x0) {
2006        FX_MEI_DMSG("Get ARC_ACK\n");
2007        got_int = 1;
2008    }
2009    else if (rd_mbox[0] == 0x5) {
2010        IFX_MEI_DMSG("Get ARC_BUSY\n");
2011        got_int = 2;
2012    }
2013    else if (rd_mbox[0] == 0x3) {
2014        IFX_MEI_DMSG("Get ARC_EDONE\n");
2015        if (rd_mbox[1] == 0x0) {
2016            got_int = 3;
2017            IFX_MEI_DMSG("Get E_MEMTEST\n");
2018            if (rd_mbox[2] != 0x1) {
2019                got_int = 4;
2020                IFX_MEI_DMSG("Get Result %X\n", rd_mbox[2]);
2021            }
2022        }
2023    }
2024    IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_ARC2ME_STAT,
2025        ARC_TO_MEI_DBG_DONE);
2026    MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DFEIR]);
2027    disable_irq (pDev->nIrq[IFX_DFEIR]);
2028    //got_int = 1;
2029    return;
2030}
2031
2032static void
2033wait_mem_test_result (void)
2034{
2035    uint32_t mbox[5];
2036    mbox[0] = 0;
2037
2038    IFX_MEI_DMSG("Waiting Starting\n");
2039    while (mbox[0] == 0) {
2040        ReadMbox (&mbox[0], 5);
2041    }
2042    IFX_MEI_DMSG("Try to get mem test result.\n");
2043    ReadMbox (&mbox[0], 5);
2044    if (mbox[0] == 0xA) {
2045        IFX_MEI_DMSG("Success.\n");
2046    }
2047    else if (mbox[0] == 0xA) {
2048        IFX_MEI_EMSG("Fail,address %X,except data %X,receive data %X\n",
2049            mbox[1], mbox[2], mbox[3]);
2050    }
2051    else {
2052        IFX_MEI_EMSG("Fail\n");
2053    }
2054}
2055
2056static int
2057arc_ping_testing (DSL_DEV_Device_t *pDev)
2058{
2059#define MEI_PING 0x00000001
2060    uint32_t wr_mbox[10], rd_mbox[10];
2061    int i;
2062
2063    for (i = 0; i < 10; i++) {
2064        wr_mbox[i] = 0;
2065        rd_mbox[i] = 0;
2066    }
2067
2068    FX_MEI_DMSG("send ping msg\n");
2069    wr_mbox[0] = MEI_PING;
2070    WriteMbox (&wr_mbox[0], 10);
2071
2072    while (got_int == 0) {
2073        MEI_WAIT (100);
2074    }
2075
2076    IFX_MEI_DMSG("send start event\n");
2077    got_int = 0;
2078
2079    wr_mbox[0] = 0x4;
2080    wr_mbox[1] = 0;
2081    wr_mbox[2] = 0;
2082    wr_mbox[3] = (uint32_t) 0xf5acc307e;
2083    wr_mbox[4] = 5;
2084    wr_mbox[5] = 2;
2085    wr_mbox[6] = 0x1c000;
2086    wr_mbox[7] = 64;
2087    wr_mbox[8] = 0;
2088    wr_mbox[9] = 0;
2089    WriteMbox (&wr_mbox[0], 10);
2090    DSL_ENABLE_IRQ (pDev->nIrq[IFX_DFEIR]);
2091    //printk("IFX_MEI_MailboxWrite ret=%d\n",i);
2092    IFX_MEI_LongWordWriteOffset (&dsl_devices[0],
2093                       (u32) ME_ME2ARC_INT,
2094                       MEI_TO_ARC_MSGAV);
2095    IFX_MEI_DMSG("sleeping\n");
2096    while (1) {
2097        if (got_int > 0) {
2098
2099            if (got_int > 3)
2100                IFX_MEI_DMSG("got_int >>>> 3\n");
2101            else
2102                IFX_MEI_DMSG("got int = %d\n", got_int);
2103            got_int = 0;
2104            //schedule();
2105            DSL_ENABLE_IRQ (pDev->nIrq[IFX_DFEIR]);
2106        }
2107        //mbox_read(&rd_mbox[0],6);
2108        MEI_WAIT (100);
2109    }
2110    return 0;
2111}
2112
2113static DSL_DEV_MeiError_t
2114DFE_Loopback_Test (void)
2115{
2116    int i = 0;
2117    u32 arc_debug_data = 0, temp;
2118    DSL_DEV_Device_t *pDev = &dsl_devices[0];
2119    uint32_t wr_mbox[10];
2120
2121    IFX_MEI_ResetARC (pDev);
2122    // start the clock
2123    arc_debug_data = ACL_CLK_MODE_ENABLE;
2124    IFX_MEI_DebugWrite (pDev, CRI_CCR0, &arc_debug_data, 1);
2125
2126#if defined( DFE_PING_TEST )|| defined( DFE_ATM_LOOPBACK)
2127    // WriteARCreg(AUX_XMEM_LTEST,0);
2128    IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
2129#define AUX_XMEM_LTEST 0x128
2130    _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK, AUX_XMEM_LTEST, 0);
2131    IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
2132
2133    // WriteARCreg(AUX_XDMA_GAP,0);
2134    IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
2135#define AUX_XDMA_GAP 0x114
2136    _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK, AUX_XDMA_GAP, 0);
2137    IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
2138
2139    IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
2140    temp = 0;
2141    _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK,
2142        (u32) ME_XDATA_BASE_SH + LTQ_MEI_BASE_ADDR, temp);
2143    IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
2144
2145    i = IFX_MEI_DFEMemoryAlloc (pDev, SDRAM_SEGMENT_SIZE * 16);
2146    if (i >= 0) {
2147        int idx;
2148
2149        for (idx = 0; idx < i; idx++) {
2150            DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].type = FREE_RELOAD;
2151            IFX_MEI_WRITE_REGISTER_L ((((uint32_t) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].address) & 0x0fffffff),
2152                            LTQ_MEI_BASE_ADDR + ME_XMEM_BAR_BASE + idx * 4);
2153            IFX_MEI_DMSG("bar%d(%X)=%X\n", idx,
2154                LTQ_MEI_BASE_ADDR + ME_XMEM_BAR_BASE +
2155                idx * 4, (((uint32_t)
2156                       ((ifx_mei_device_private_t *)
2157                        pDev->pPriv)->adsl_mem_info[idx].
2158                       address) & 0x0fffffff));
2159            memset ((u8 *) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].address, 0, SDRAM_SEGMENT_SIZE);
2160        }
2161
2162        IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XDATA_BASE_SH,
2163                       ((unsigned long) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[XDATA_REGISTER].address) & 0x0FFFFFFF);
2164    }
2165    else {
2166        IFX_MEI_EMSG ("cannot load image: no memory\n");
2167        return DSL_DEV_MEI_ERR_FAILURE;
2168    }
2169    //WriteARCreg(AUX_IC_CTRL,2);
2170    IFX_MEI_DMSG("Setting MEI_MASTER_MODE..\n");
2171    IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
2172#define AUX_IC_CTRL 0x11
2173    _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK,
2174                     AUX_IC_CTRL, 2);
2175    IFX_MEI_DMSG("Setting JTAG_MASTER_MODE..\n");
2176    IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
2177
2178    IFX_MEI_DMSG("Halting ARC...\n");
2179    IFX_MEI_HaltArc (&dsl_devices[0]);
2180
2181#ifdef DFE_PING_TEST
2182
2183    IFX_MEI_DMSG("ping test image size=%d\n", sizeof (arc_ahb_access_code));
2184    memcpy ((u8 *) (DSL_DEV_PRIVATE(pDev)->
2185            adsl_mem_info[0].address + 0x1004),
2186        &arc_ahb_access_code[0], sizeof (arc_ahb_access_code));
2187    load_jump_table (0x80000 + 0x1004);
2188
2189#endif //DFE_PING_TEST
2190
2191    IFX_MEI_DMSG("ARC ping test code download complete\n");
2192#endif //defined( DFE_PING_TEST )|| defined( DFE_ATM_LOOPBACK)
2193#ifdef DFE_MEM_TEST
2194    IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_ARC2ME_MASK, MSGAV_EN);
2195
2196    arc_code_page_download (1537, &code_array[0]);
2197    IFX_MEI_DMSG("ARC mem test code download complete\n");
2198#endif //DFE_MEM_TEST
2199#ifdef DFE_ATM_LOOPBACK
2200    arc_debug_data = 0xf;
2201    arc_code_page_download (sizeof(code_array) / sizeof(*code_array), &code_array[0]);
2202    wr_mbox[0] = 0; //TIMER_DELAY - org: 1024
2203    wr_mbox[1] = 0; //TXFB_START0
2204    wr_mbox[2] = 0x7f; //TXFB_END0 - org: 49
2205    wr_mbox[3] = 0x80; //TXFB_START1 - org: 80
2206    wr_mbox[4] = 0xff; //TXFB_END1 - org: 109
2207    wr_mbox[5] = 0x100; //RXFB_START0 - org: 0
2208    wr_mbox[6] = 0x17f; //RXFB_END0 - org: 49
2209    wr_mbox[7] = 0x180; //RXFB_START1 - org: 256
2210    wr_mbox[8] = 0x1ff; //RXFB_END1 - org: 315
2211    WriteMbox (&wr_mbox[0], 9);
2212    // Start Iridia IT_AMODE (in dmp access) why is it required?
2213    IFX_MEI_DebugWrite (&dsl_devices[0], 0x32010, &arc_debug_data, 1);
2214#endif //DFE_ATM_LOOPBACK
2215    IFX_MEI_IRQEnable (pDev);
2216    IFX_MEI_DMSG("run ARC...\n");
2217    IFX_MEI_RunArc (&dsl_devices[0]);
2218
2219#ifdef DFE_PING_TEST
2220    arc_ping_testing (pDev);
2221#endif //DFE_PING_TEST
2222#ifdef DFE_MEM_TEST
2223    wait_mem_test_result ();
2224#endif //DFE_MEM_TEST
2225
2226    IFX_MEI_DFEMemoryFree (pDev, FREE_ALL);
2227    return DSL_DEV_MEI_ERR_SUCCESS;
2228}
2229
2230#endif //CONFIG_AMAZON_S_MEI_FW_LOOPBACK
2231
2232static int
2233IFX_MEI_InitDevNode (int num)
2234{
2235    if (num == 0) {
2236        if ((dev_major = register_chrdev (dev_major, IFX_MEI_DEVNAME, &bsp_mei_operations)) < 0) {
2237            IFX_MEI_EMSG ("register_chrdev(%d %s) failed!\n", dev_major, IFX_MEI_DEVNAME);
2238            return -ENODEV;
2239        }
2240    }
2241    return 0;
2242}
2243
2244static int
2245IFX_MEI_CleanUpDevNode (int num)
2246{
2247    if (num == 0)
2248        unregister_chrdev (dev_major, MEI_DIRNAME);
2249    return 0;
2250}
2251
2252static int
2253IFX_MEI_InitDevice (int num)
2254{
2255    DSL_DEV_Device_t *pDev;
2256        u32 temp;
2257    pDev = &dsl_devices[num];
2258    if (pDev == NULL)
2259        return -ENOMEM;
2260    pDev->pPriv = &sDanube_Mei_Private[num];
2261    memset (pDev->pPriv, 0, sizeof (ifx_mei_device_private_t));
2262
2263    memset (&DSL_DEV_PRIVATE(pDev)->
2264        adsl_mem_info[0], 0,
2265        sizeof (smmu_mem_info_t) * MAX_BAR_REGISTERS);
2266
2267    if (num == 0) {
2268        pDev->nIrq[IFX_DFEIR] = LTQ_MEI_INT;
2269        pDev->nIrq[IFX_DYING_GASP] = LTQ_MEI_DYING_GASP_INT;
2270        pDev->base_address = KSEG1 + LTQ_MEI_BASE_ADDR;
2271
2272                /* Power up MEI */
2273#ifdef CONFIG_LANTIQ_AMAZON_SE
2274        *LTQ_PMU_PWDCR &= ~(1 << 9); // enable dsl
2275                *LTQ_PMU_PWDCR &= ~(1 << 15); // enable AHB base
2276#else
2277            temp = ltq_r32(LTQ_PMU_PWDCR);
2278            temp &= 0xffff7dbe;
2279            ltq_w32(temp, LTQ_PMU_PWDCR);
2280#endif
2281    }
2282    pDev->nInUse = 0;
2283    DSL_DEV_PRIVATE(pDev)->modem_ready = 0;
2284    DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
2285
2286    MEI_INIT_WAKELIST ("arcq", DSL_DEV_PRIVATE(pDev)->wait_queue_arcmsgav); // for ARCMSGAV
2287    MEI_INIT_WAKELIST ("arcr", DSL_DEV_PRIVATE(pDev)->wait_queue_modemready); // for arc modem ready
2288
2289    MEI_MUTEX_INIT (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema, 1); // semaphore initialization, mutex
2290#if 0
2291    MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DFEIR]);
2292    MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DYING_GASP]);
2293#endif
2294    if (request_irq (pDev->nIrq[IFX_DFEIR], IFX_MEI_IrqHandle, 0, "DFEIR", pDev) != 0) {
2295        IFX_MEI_EMSG ("request_irq %d failed!\n", pDev->nIrq[IFX_DFEIR]);
2296        return -1;
2297    }
2298    /*if (request_irq (pDev->nIrq[IFX_DYING_GASP], IFX_MEI_Dying_Gasp_IrqHandle, 0, "DYING_GASP", pDev) != 0) {
2299        IFX_MEI_EMSG ("request_irq %d failed!\n", pDev->nIrq[IFX_DYING_GASP]);
2300        return -1;
2301    }*/
2302// IFX_MEI_DMSG("Device %d initialized. IER %#x\n", num, bsp_get_irq_ier(pDev->nIrq[IFX_DYING_GASP]));
2303    return 0;
2304}
2305
2306static int
2307IFX_MEI_ExitDevice (int num)
2308{
2309    DSL_DEV_Device_t *pDev;
2310    pDev = &dsl_devices[num];
2311
2312    if (pDev == NULL)
2313        return -EIO;
2314
2315    disable_irq (pDev->nIrq[IFX_DFEIR]);
2316    disable_irq (pDev->nIrq[IFX_DYING_GASP]);
2317
2318    free_irq(pDev->nIrq[IFX_DFEIR], pDev);
2319    free_irq(pDev->nIrq[IFX_DYING_GASP], pDev);
2320
2321    return 0;
2322}
2323
2324static DSL_DEV_Device_t *
2325IFX_BSP_HandleGet (int maj, int num)
2326{
2327    if (num > BSP_MAX_DEVICES)
2328        return NULL;
2329    return &dsl_devices[num];
2330}
2331
2332DSL_DEV_Device_t *
2333DSL_BSP_DriverHandleGet (int maj, int num)
2334{
2335    DSL_DEV_Device_t *pDev;
2336
2337    if (num > BSP_MAX_DEVICES)
2338        return NULL;
2339
2340    pDev = &dsl_devices[num];
2341    if (!try_module_get(pDev->owner))
2342        return NULL;
2343
2344    pDev->nInUse++;
2345    return pDev;
2346}
2347
2348int
2349DSL_BSP_DriverHandleDelete (DSL_DEV_Device_t * nHandle)
2350{
2351    DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) nHandle;
2352    if (pDev->nInUse)
2353        pDev->nInUse--;
2354        module_put(pDev->owner);
2355    return 0;
2356}
2357
2358static int
2359IFX_MEI_Open (DSL_DRV_inode_t * ino, DSL_DRV_file_t * fil)
2360{
2361    int maj = MAJOR (ino->i_rdev);
2362    int num = MINOR (ino->i_rdev);
2363
2364    DSL_DEV_Device_t *pDev = NULL;
2365    if ((pDev = DSL_BSP_DriverHandleGet (maj, num)) == NULL) {
2366        IFX_MEI_EMSG("open(%d:%d) fail!\n", maj, num);
2367        return -EIO;
2368    }
2369    fil->private_data = pDev;
2370    return 0;
2371}
2372
2373static int
2374IFX_MEI_Release (DSL_DRV_inode_t * ino, DSL_DRV_file_t * fil)
2375{
2376    //int maj = MAJOR(ino->i_rdev);
2377    int num = MINOR (ino->i_rdev);
2378    DSL_DEV_Device_t *pDev;
2379
2380    pDev = &dsl_devices[num];
2381    if (pDev == NULL)
2382        return -EIO;
2383    DSL_BSP_DriverHandleDelete (pDev);
2384    return 0;
2385}
2386
2387/**
2388 * Callback function for linux userspace program writing
2389 */
2390static ssize_t
2391IFX_MEI_Write (DSL_DRV_file_t * filp, const char *buf, size_t size, loff_t * loff)
2392{
2393    DSL_DEV_MeiError_t mei_error = DSL_DEV_MEI_ERR_FAILURE;
2394    long offset = 0;
2395    DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) filp->private_data;
2396
2397    if (pDev == NULL)
2398        return -EIO;
2399
2400    mei_error =
2401        DSL_BSP_FWDownload (pDev, buf, size, (long *) loff, &offset);
2402
2403    if (mei_error == DSL_DEV_MEI_ERR_FAILURE)
2404        return -EIO;
2405    return (ssize_t) offset;
2406}
2407
2408/**
2409 * Callback function for linux userspace program ioctling
2410 */
2411static int
2412IFX_MEI_IoctlCopyFrom (int from_kernel, char *dest, char *from, int size)
2413{
2414    int ret = 0;
2415
2416    if (!from_kernel)
2417        ret = copy_from_user ((char *) dest, (char *) from, size);
2418    else
2419        ret = (int)memcpy ((char *) dest, (char *) from, size);
2420    return ret;
2421}
2422
2423static int
2424IFX_MEI_IoctlCopyTo (int from_kernel, char *dest, char *from, int size)
2425{
2426    int ret = 0;
2427
2428    if (!from_kernel)
2429        ret = copy_to_user ((char *) dest, (char *) from, size);
2430    else
2431        ret = (int)memcpy ((char *) dest, (char *) from, size);
2432    return ret;
2433}
2434
2435int
2436IFX_MEI_Ioctls (DSL_DEV_Device_t * pDev, int from_kernel, unsigned int command, unsigned long lon)
2437{
2438    int i = 0;
2439    int meierr = DSL_DEV_MEI_ERR_SUCCESS;
2440    u32 base_address = LTQ_MEI_BASE_ADDR;
2441    DSL_DEV_WinHost_Message_t winhost_msg, m;
2442// DSL_DEV_MeiDebug_t debugrdwr;
2443    DSL_DEV_MeiReg_t regrdwr;
2444
2445    switch (command) {
2446
2447    case DSL_FIO_BSP_CMV_WINHOST:
2448        IFX_MEI_IoctlCopyFrom (from_kernel, (char *) winhost_msg.msg.TxMessage,
2449                         (char *) lon, MSG_LENGTH * 2);
2450
2451        if ((meierr = DSL_BSP_SendCMV (pDev, winhost_msg.msg.TxMessage, YES_REPLY,
2452                       winhost_msg.msg.RxMessage)) != DSL_DEV_MEI_ERR_SUCCESS) {
2453            IFX_MEI_EMSG ("WINHOST CMV fail :TxMessage:%X %X %X %X, RxMessage:%X %X %X %X %X\n",
2454                 winhost_msg.msg.TxMessage[0], winhost_msg.msg.TxMessage[1], winhost_msg.msg.TxMessage[2], winhost_msg.msg.TxMessage[3],
2455                 winhost_msg.msg.RxMessage[0], winhost_msg.msg.RxMessage[1], winhost_msg.msg.RxMessage[2], winhost_msg.msg.RxMessage[3],
2456                 winhost_msg.msg.RxMessage[4]);
2457            meierr = DSL_DEV_MEI_ERR_FAILURE;
2458        }
2459        else {
2460            IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
2461                           (char *) winhost_msg.msg.RxMessage,
2462                           MSG_LENGTH * 2);
2463        }
2464        break;
2465
2466    case DSL_FIO_BSP_CMV_READ:
2467        IFX_MEI_IoctlCopyFrom (from_kernel, (char *) (&regrdwr),
2468                         (char *) lon, sizeof (DSL_DEV_MeiReg_t));
2469
2470        IFX_MEI_LongWordRead ((u32) regrdwr.iAddress,
2471                        (u32 *) & (regrdwr.iData));
2472
2473        IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
2474                       (char *) (&regrdwr),
2475                       sizeof (DSL_DEV_MeiReg_t));
2476
2477        break;
2478
2479    case DSL_FIO_BSP_CMV_WRITE:
2480        IFX_MEI_IoctlCopyFrom (from_kernel, (char *) (&regrdwr),
2481                         (char *) lon, sizeof (DSL_DEV_MeiReg_t));
2482
2483        IFX_MEI_LongWordWrite ((u32) regrdwr.iAddress,
2484                         regrdwr.iData);
2485        break;
2486
2487    case DSL_FIO_BSP_GET_BASE_ADDRESS:
2488        IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
2489                       (char *) (&base_address),
2490                       sizeof (base_address));
2491        break;
2492
2493    case DSL_FIO_BSP_IS_MODEM_READY:
2494        i = IFX_MEI_IsModemReady (pDev);
2495        IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
2496                       (char *) (&i), sizeof (int));
2497        meierr = DSL_DEV_MEI_ERR_SUCCESS;
2498        break;
2499    case DSL_FIO_BSP_RESET:
2500    case DSL_FIO_BSP_REBOOT:
2501        meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_RESET);
2502        meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_HALT);
2503        break;
2504
2505    case DSL_FIO_BSP_HALT:
2506        meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_HALT);
2507        break;
2508
2509    case DSL_FIO_BSP_RUN:
2510        meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_RUN);
2511        break;
2512    case DSL_FIO_BSP_BOOTDOWNLOAD:
2513        meierr = IFX_MEI_DownloadBootCode (pDev);
2514        break;
2515    case DSL_FIO_BSP_JTAG_ENABLE:
2516        meierr = IFX_MEI_ArcJtagEnable (pDev, 1);
2517        break;
2518
2519    case DSL_FIO_BSP_REMOTE:
2520        IFX_MEI_IoctlCopyFrom (from_kernel, (char *) (&i),
2521                         (char *) lon, sizeof (int));
2522
2523        meierr = IFX_MEI_AdslMailboxIRQEnable (pDev, i);
2524        break;
2525
2526    case DSL_FIO_BSP_DSL_START:
2527        IFX_MEI_DMSG("DSL_FIO_BSP_DSL_START\n");
2528        if ((meierr = IFX_MEI_RunAdslModem (pDev)) != DSL_DEV_MEI_ERR_SUCCESS) {
2529            IFX_MEI_EMSG ("IFX_MEI_RunAdslModem() error...");
2530            meierr = DSL_DEV_MEI_ERR_FAILURE;
2531        }
2532        break;
2533
2534/* case DSL_FIO_BSP_DEBUG_READ:
2535    case DSL_FIO_BSP_DEBUG_WRITE:
2536        IFX_MEI_IoctlCopyFrom (from_kernel,
2537                         (char *) (&debugrdwr),
2538                         (char *) lon,
2539                         sizeof (debugrdwr));
2540
2541        if (command == DSL_FIO_BSP_DEBUG_READ)
2542            meierr = DSL_BSP_MemoryDebugAccess (pDev,
2543                                 DSL_BSP_MEMORY_READ,
2544                                 debugrdwr.
2545                                 iAddress,
2546                                 debugrdwr.
2547                                 buffer,
2548                                 debugrdwr.
2549                                 iCount);
2550        else
2551            meierr = DSL_BSP_MemoryDebugAccess (pDev,
2552                                 DSL_BSP_MEMORY_WRITE,
2553                                 debugrdwr.
2554                                 iAddress,
2555                                 debugrdwr.
2556                                 buffer,
2557                                 debugrdwr.
2558                                 iCount);
2559
2560        IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon, (char *) (&debugrdwr), sizeof (debugrdwr));
2561        break;*/
2562    case DSL_FIO_BSP_GET_VERSION:
2563        IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon, (char *) (&bsp_mei_version), sizeof (DSL_DEV_Version_t));
2564        break;
2565
2566#define LTQ_MPS_CHIPID_VERSION_GET(value) (((value) >> 28) & ((1 << 4) - 1))
2567    case DSL_FIO_BSP_GET_CHIP_INFO:
2568                bsp_chip_info.major = 1;
2569                bsp_chip_info.minor = LTQ_MPS_CHIPID_VERSION_GET(*LTQ_MPS_CHIPID);
2570                IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon, (char *) (&bsp_chip_info), sizeof (DSL_DEV_HwVersion_t));
2571                meierr = DSL_DEV_MEI_ERR_SUCCESS;
2572        break;
2573
2574        case DSL_FIO_BSP_FREE_RESOURCE:
2575                makeCMV (H2D_CMV_READ, DSL_CMV_GROUP_STAT, 4, 0, 1, NULL, m.msg.TxMessage);
2576                if (DSL_BSP_SendCMV (pDev, m.msg.TxMessage, YES_REPLY, m.msg.RxMessage) != DSL_DEV_MEI_ERR_SUCCESS) {
2577                        meierr = DSL_DEV_MEI_ERR_FAILURE;
2578                        return -EIO;
2579                }
2580                IFX_MEI_DMSG("RxMessage[4] = %#x\n", m.msg.RxMessage[4]);
2581                if (!(m.msg.RxMessage[4] & DSL_DEV_STAT_CODESWAP_COMPLETE)) {
2582                        meierr = DSL_DEV_MEI_ERR_FAILURE;
2583                        return -EAGAIN;
2584                }
2585                IFX_MEI_DMSG("Freeing all memories marked FREE_SHOWTIME\n");
2586                IFX_MEI_DFEMemoryFree (pDev, FREE_SHOWTIME);
2587                meierr = DSL_DEV_MEI_ERR_SUCCESS;
2588        break;
2589#ifdef CONFIG_IFXMIPS_AMAZON_SE
2590    case DSL_FIO_ARC_MUX_TEST:
2591        AMAZON_SE_MEI_ARC_MUX_Test();
2592        break;
2593#endif
2594    default:
2595// IFX_MEI_EMSG("Invalid IOCTL command: %d\n");
2596        break;
2597    }
2598    return meierr;
2599}
2600
2601#ifdef CONFIG_IFXMIPS_AMAZON_SE
2602void AMAZON_SE_MEI_ARC_MUX_Test(void)
2603{
2604    u32 *p, i;
2605    *LTQ_RCU_RST |= LTQ_RCU_RST_REQ_MUX_ARC;
2606
2607    p = (u32*)(DFE_LDST_BASE_ADDR + IRAM0_BASE);
2608    IFX_MEI_EMSG("Writing to IRAM0(%p)...\n", p);
2609    for (i = 0; i < IRAM0_SIZE/sizeof(u32); i++, p++) {
2610        *p = 0xdeadbeef;
2611        if (*p != 0xdeadbeef)
2612            IFX_MEI_EMSG("%p: %#x\n", p, *p);
2613    }
2614
2615    p = (u32*)(DFE_LDST_BASE_ADDR + IRAM1_BASE);
2616    IFX_MEI_EMSG("Writing to IRAM1(%p)...\n", p);
2617    for (i = 0; i < IRAM1_SIZE/sizeof(u32); i++, p++) {
2618        *p = 0xdeadbeef;
2619        if (*p != 0xdeadbeef)
2620            IFX_MEI_EMSG("%p: %#x\n", p, *p);
2621    }
2622
2623    p = (u32*)(DFE_LDST_BASE_ADDR + BRAM_BASE);
2624    IFX_MEI_EMSG("Writing to BRAM(%p)...\n", p);
2625    for (i = 0; i < BRAM_SIZE/sizeof(u32); i++, p++) {
2626        *p = 0xdeadbeef;
2627        if (*p != 0xdeadbeef)
2628            IFX_MEI_EMSG("%p: %#x\n", p, *p);
2629    }
2630
2631    p = (u32*)(DFE_LDST_BASE_ADDR + XRAM_BASE);
2632    IFX_MEI_EMSG("Writing to XRAM(%p)...\n", p);
2633    for (i = 0; i < XRAM_SIZE/sizeof(u32); i++, p++) {
2634        *p = 0xdeadbeef;
2635        if (*p != 0xdeadbeef)
2636            IFX_MEI_EMSG("%p: %#x\n", p, *p);
2637    }
2638
2639    p = (u32*)(DFE_LDST_BASE_ADDR + YRAM_BASE);
2640    IFX_MEI_EMSG("Writing to YRAM(%p)...\n", p);
2641    for (i = 0; i < YRAM_SIZE/sizeof(u32); i++, p++) {
2642        *p = 0xdeadbeef;
2643        if (*p != 0xdeadbeef)
2644            IFX_MEI_EMSG("%p: %#x\n", p, *p);
2645    }
2646
2647    p = (u32*)(DFE_LDST_BASE_ADDR + EXT_MEM_BASE);
2648    IFX_MEI_EMSG("Writing to EXT_MEM(%p)...\n", p);
2649    for (i = 0; i < EXT_MEM_SIZE/sizeof(u32); i++, p++) {
2650        *p = 0xdeadbeef;
2651        if (*p != 0xdeadbeef)
2652            IFX_MEI_EMSG("%p: %#x\n", p, *p);
2653    }
2654    *LTQ_RCU_RST &= ~LTQ_RCU_RST_REQ_MUX_ARC;
2655}
2656#endif
2657int
2658DSL_BSP_KernelIoctls (DSL_DEV_Device_t * pDev, unsigned int command,
2659               unsigned long lon)
2660{
2661    int error = 0;
2662
2663    error = IFX_MEI_Ioctls (pDev, 1, command, lon);
2664    return error;
2665}
2666
2667static long
2668IFX_MEI_UserIoctls (DSL_DRV_file_t * fil,
2669              unsigned int command, unsigned long lon)
2670{
2671    int error = 0;
2672    DSL_DEV_Device_t *pDev;
2673
2674    pDev = IFX_BSP_HandleGet (0, 0);
2675    if (pDev == NULL)
2676        return -EIO;
2677
2678    error = IFX_MEI_Ioctls (pDev, 0, command, lon);
2679    return error;
2680}
2681
2682static int adsl_dummy_ledcallback(void)
2683{
2684    return 0;
2685}
2686
2687int ifx_mei_atm_led_blink(void)
2688{
2689    return g_adsl_ledcallback();
2690}
2691EXPORT_SYMBOL(ifx_mei_atm_led_blink);
2692
2693int ifx_mei_atm_showtime_check(int *is_showtime, struct port_cell_info *port_cell, void **xdata_addr)
2694{
2695    int i;
2696
2697    if ( is_showtime ) {
2698        *is_showtime = g_tx_link_rate[0] == 0 && g_tx_link_rate[1] == 0 ? 0 : 1;
2699    }
2700
2701    if ( port_cell ) {
2702        for ( i = 0; i < port_cell->port_num && i < 2; i++ )
2703            port_cell->tx_link_rate[i] = g_tx_link_rate[i];
2704    }
2705
2706    if ( xdata_addr ) {
2707        if ( g_tx_link_rate[0] == 0 && g_tx_link_rate[1] == 0 )
2708            *xdata_addr = NULL;
2709        else
2710            *xdata_addr = g_xdata_addr;
2711    }
2712
2713    return 0;
2714}
2715EXPORT_SYMBOL(ifx_mei_atm_showtime_check);
2716
2717/*
2718 * Writing function for linux proc filesystem
2719 */
2720static int __devinit ltq_mei_probe(struct platform_device *pdev)
2721{
2722    int i = 0;
2723    static struct class *dsl_class;
2724
2725    pr_info("IFX MEI Version %ld.%02ld.%02ld\n", bsp_mei_version.major, bsp_mei_version.minor, bsp_mei_version.revision);
2726
2727    for (i = 0; i < BSP_MAX_DEVICES; i++) {
2728        if (IFX_MEI_InitDevice (i) != 0) {
2729            IFX_MEI_EMSG("Init device fail!\n");
2730            return -EIO;
2731        }
2732        IFX_MEI_InitDevNode (i);
2733    }
2734        for (i = 0; i <= DSL_BSP_CB_LAST ; i++)
2735        dsl_bsp_event_callback[i].function = NULL;
2736
2737#ifdef CONFIG_LTQ_MEI_FW_LOOPBACK
2738    IFX_MEI_DMSG("Start loopback test...\n");
2739    DFE_Loopback_Test ();
2740#endif
2741    dsl_class = class_create(THIS_MODULE, "ifx_mei");
2742    device_create(dsl_class, NULL, MKDEV(MEI_MAJOR, 0), NULL, "ifx_mei");
2743    return 0;
2744}
2745
2746static int __devexit ltq_mei_remove(struct platform_device *pdev)
2747{
2748    int i = 0;
2749    int num;
2750
2751    for (num = 0; num < BSP_MAX_DEVICES; num++) {
2752        IFX_MEI_CleanUpDevNode (num);
2753    }
2754
2755    for (i = 0; i < BSP_MAX_DEVICES; i++) {
2756        for (i = 0; i < BSP_MAX_DEVICES; i++) {
2757            IFX_MEI_ExitDevice (i);
2758        }
2759    }
2760    return 0;
2761}
2762
2763static const struct of_device_id ltq_mei_match[] = {
2764    { .compatible = "lantiq,mei-xway"},
2765    {},
2766};
2767
2768static struct platform_driver ltq_mei_driver = {
2769    .probe = ltq_mei_probe,
2770    .remove = __devexit_p(ltq_mei_remove),
2771    .driver = {
2772        .name = "lantiq,mei-xway",
2773        .owner = THIS_MODULE,
2774        .of_match_table = ltq_mei_match,
2775    },
2776};
2777
2778module_platform_driver(ltq_mei_driver);
2779
2780/* export function for DSL Driver */
2781
2782/* The functions of MEI_DriverHandleGet and MEI_DriverHandleDelete are
2783something like open/close in kernel space , where the open could be used
2784to register a callback for autonomous messages and returns a mei driver context pointer (comparable to the file descriptor in user space)
2785   The context will be required for the multi line chips future! */
2786
2787EXPORT_SYMBOL (DSL_BSP_DriverHandleGet);
2788EXPORT_SYMBOL (DSL_BSP_DriverHandleDelete);
2789
2790EXPORT_SYMBOL (DSL_BSP_ATMLedCBRegister);
2791EXPORT_SYMBOL (DSL_BSP_ATMLedCBUnregister);
2792EXPORT_SYMBOL (DSL_BSP_KernelIoctls);
2793EXPORT_SYMBOL (DSL_BSP_AdslLedInit);
2794//EXPORT_SYMBOL (DSL_BSP_AdslLedSet);
2795EXPORT_SYMBOL (DSL_BSP_FWDownload);
2796EXPORT_SYMBOL (DSL_BSP_Showtime);
2797
2798EXPORT_SYMBOL (DSL_BSP_MemoryDebugAccess);
2799EXPORT_SYMBOL (DSL_BSP_SendCMV);
2800
2801// provide a register/unregister function for DSL driver to register a event callback function
2802EXPORT_SYMBOL (DSL_BSP_EventCBRegister);
2803EXPORT_SYMBOL (DSL_BSP_EventCBUnregister);
2804
2805MODULE_LICENSE("Dual BSD/GPL");
2806

Archive Download this file



interactive