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

Archive Download this file



interactive