1 /******************************************************************************
4 Infineon Technologies AG
5 Am Campeon 1-12; 81726 Munich, Germany
7 For licensing information, see the file 'LICENSE' in the root folder of
10 ******************************************************************************/
13 \defgroup AMAZON_S_MEI Amazon-S MEI Driver Module
14 \brief Amazon-S MEI driver module
18 \defgroup Internal Compile Parametere
20 \brief exported functions for other driver use
24 \file amazon_s_mei_bsp.c
26 \brief Amazon-S MEI driver file
29 #include <linux/kernel.h>
30 #include <linux/module.h>
31 #include <linux/version.h>
32 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33))
33 #include <linux/utsrelease.h>
35 #include <generated/utsrelease.h>
37 #include <linux/types.h>
40 #include <linux/errno.h>
41 #include <linux/interrupt.h>
42 #include <linux/netdevice.h>
43 #include <linux/etherdevice.h>
44 #include <linux/proc_fs.h>
45 #include <linux/init.h>
46 #include <linux/ioport.h>
47 #include <linux/delay.h>
48 #include <linux/device.h>
49 #include <linux/sched.h>
50 #include <asm/uaccess.h>
51 #include <asm/hardirq.h>
53 #include <lantiq_soc.h>
54 #include "ifxmips_atm.h"
56 #include "ifxmips_mei_interface.h"
58 /*#define LTQ_RCU_RST IFX_RCU_RST_REQ
59 #define LTQ_RCU_RST_REQ_ARC_JTAG IFX_RCU_RST_REQ_ARC_JTAG
60 #define LTQ_RCU_RST_REQ_DFE IFX_RCU_RST_REQ_DFE
61 #define LTQ_RCU_RST_REQ_AFE IFX_RCU_RST_REQ_AFE
62 #define IFXMIPS_FUSE_BASE_ADDR IFX_FUSE_BASE_ADDR
63 #define IFXMIPS_ICU_IM0_IER IFX_ICU_IM0_IER
64 #define IFXMIPS_ICU_IM2_IER IFX_ICU_IM2_IER
65 #define LTQ_MEI_INT IFX_MEI_INT
66 #define LTQ_MEI_DYING_GASP_INT IFX_MEI_DYING_GASP_INT
67 #define LTQ_MEI_BASE_ADDR IFX_MEI_SPACE_ACCESS
68 #define IFXMIPS_PMU_PWDCR IFX_PMU_PWDCR
69 #define IFXMIPS_MPS_CHIPID IFX_MPS_CHIPID
71 #define ifxmips_port_reserve_pin ifx_gpio_pin_reserve
72 #define ifxmips_port_set_dir_in ifx_gpio_dir_in_set
73 #define ifxmips_port_clear_altsel0 ifx_gpio_altsel0_set
74 #define ifxmips_port_clear_altsel1 ifx_gpio_altsel1_clear
75 #define ifxmips_port_set_open_drain ifx_gpio_open_drain_clear
76 #define ifxmips_port_free_pin ifx_gpio_pin_free
77 #define ifxmips_mask_and_ack_irq bsp_mask_and_ack_irq
78 #define IFXMIPS_MPS_CHIPID_VERSION_GET IFX_MCD_CHIPID_VERSION_GET
79 #define ltq_r32(reg) __raw_readl(reg)
80 #define ltq_w32(val, reg) __raw_writel(val, reg)
81 #define ltq_w32_mask(clear, set, reg) ltq_w32((ltq_r32(reg) & ~clear) | set, reg)
84 #define LTQ_RCU_BASE_ADDR 0x1F203000
85 #define LTQ_ICU_BASE_ADDR 0x1F880200
86 #define LTQ_MEI_BASE_ADDR 0x1E116000
87 #define LTQ_PMU_BASE_ADDR 0x1F102000
88 #define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21)
89 #define LTQ_USB_OC_INT (INT_NUM_IM4_IRL0 + 23)
90 #define LTQ_MEI_INT (INT_NUM_IM1_IRL0 + 23)
92 #define LTQ_RCU_RST_REQ_DFE (1 << 7)
93 #define LTQ_RCU_RST_REQ_AFE (1 << 11)
95 #define LTQ_PMU_BASE (KSEG1 + LTQ_PMU_BASE_ADDR)
96 #define LTQ_RCU_BASE (KSEG1 + LTQ_RCU_BASE_ADDR)
97 #define LTQ_ICU_BASE (KSEG1 + LTQ_ICU_BASE_ADDR)
99 #define LTQ_PMU_PWDCR ((u32 *)(LTQ_PMU_BASE + 0x001C))
100 #define LTQ_PMU_PWDSR ((u32 *)(LTQ_PMU_BASE + 0x0020))
101 #define LTQ_RCU_RST ((u32 *)(LTQ_RCU_BASE + 0x0010))
102 #define LTQ_RCU_RST_ALL 0x40000000
104 #define LTQ_ICU_IM0_ISR ((u32 *)(LTQ_ICU_BASE + 0x0000))
105 #define LTQ_ICU_IM0_IER ((u32 *)(LTQ_ICU_BASE + 0x0008))
106 #define LTQ_ICU_IM0_IOSR ((u32 *)(LTQ_ICU_BASE + 0x0010))
107 #define LTQ_ICU_IM0_IRSR ((u32 *)(LTQ_ICU_BASE + 0x0018))
108 #define LTQ_ICU_IM0_IMR ((u32 *)(LTQ_ICU_BASE + 0x0020))
111 #define LTQ_ICU_IM1_ISR ((u32 *)(LTQ_ICU_BASE + 0x0028))
112 #define LTQ_ICU_IM2_ISR ((u32 *)(LTQ_ICU_BASE + 0x0050))
113 #define LTQ_ICU_IM3_ISR ((u32 *)(LTQ_ICU_BASE + 0x0078))
114 #define LTQ_ICU_IM4_ISR ((u32 *)(LTQ_ICU_BASE + 0x00A0))
116 #define LTQ_ICU_OFFSET (LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR)
117 #define LTQ_ICU_IM2_IER (LTQ_ICU_IM0_IER + LTQ_ICU_OFFSET)
119 #define IFX_MEI_EMSG(fmt, args...) pr_err("[%s %d]: " fmt,__FUNCTION__, __LINE__, ## args)
120 #define IFX_MEI_DMSG(fmt, args...) pr_debug("[%s %d]: " fmt,__FUNCTION__, __LINE__, ## args)
122 #define LTQ_FUSE_BASE (KSEG1 + 0x1F107354)
124 #ifdef CONFIG_LTQ_MEI_FW_LOOPBACK
125 //#define DFE_MEM_TEST
126 //#define DFE_PING_TEST
127 #define DFE_ATM_LOOPBACK
130 #ifdef DFE_ATM_LOOPBACK
131 #include <asm/ifxmips/ifxmips_mei_fw_loopback.h>
134 void dfe_loopback_irq_handler (DSL_DEV_Device_t *pDev);
136 #endif //CONFIG_AMAZON_S_MEI_FW_LOOPBACK
138 DSL_DEV_Version_t bsp_mei_version = {
143 DSL_DEV_HwVersion_t bsp_chip_info;
145 #define IFX_MEI_DEVNAME "ifx_mei"
146 #define BSP_MAX_DEVICES 1
148 DSL_DEV_MeiError_t DSL_BSP_FWDownload (DSL_DEV_Device_t *, const char *, unsigned long, long *, long *);
149 DSL_DEV_MeiError_t DSL_BSP_Showtime (DSL_DEV_Device_t *, DSL_uint32_t, DSL_uint32_t);
150 DSL_DEV_MeiError_t DSL_BSP_AdslLedInit (DSL_DEV_Device_t *, DSL_DEV_LedId_t, DSL_DEV_LedType_t, DSL_DEV_LedHandler_t);
151 //DSL_DEV_MeiError_t DSL_BSP_AdslLedSet (DSL_DEV_Device_t *, DSL_DEV_LedId_t, DSL_DEV_LedMode_t);
152 DSL_DEV_MeiError_t DSL_BSP_MemoryDebugAccess (DSL_DEV_Device_t *, DSL_BSP_MemoryAccessType_t, DSL_uint32_t, DSL_uint32_t*, DSL_uint32_t);
153 DSL_DEV_MeiError_t DSL_BSP_SendCMV (DSL_DEV_Device_t *, u16 *, int, u16 *);
155 int DSL_BSP_KernelIoctls (DSL_DEV_Device_t *, unsigned int, unsigned long);
157 static DSL_DEV_MeiError_t IFX_MEI_RunAdslModem (DSL_DEV_Device_t *);
158 static DSL_DEV_MeiError_t IFX_MEI_CpuModeSet (DSL_DEV_Device_t *, DSL_DEV_CpuMode_t);
159 static DSL_DEV_MeiError_t IFX_MEI_DownloadBootCode (DSL_DEV_Device_t *);
160 static DSL_DEV_MeiError_t IFX_MEI_ArcJtagEnable (DSL_DEV_Device_t *, int);
161 static DSL_DEV_MeiError_t IFX_MEI_AdslMailboxIRQEnable (DSL_DEV_Device_t *, int);
163 static int IFX_MEI_GetPage (DSL_DEV_Device_t *, u32, u32, u32, u32 *, u32 *);
164 static int IFX_MEI_BarUpdate (DSL_DEV_Device_t *, int);
166 static ssize_t IFX_MEI_Write (DSL_DRV_file_t *, const char *, size_t, loff_t *);
167 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36))
168 static int IFX_MEI_UserIoctls (DSL_DRV_inode_t *, DSL_DRV_file_t *, unsigned int, unsigned long);
170 static int IFX_MEI_UserIoctls (DSL_DRV_file_t *, unsigned int, unsigned long);
172 static int IFX_MEI_Open (DSL_DRV_inode_t *, DSL_DRV_file_t *);
173 static int IFX_MEI_Release (DSL_DRV_inode_t *, DSL_DRV_file_t *);
175 void AMAZON_SE_MEI_ARC_MUX_Test(void);
177 #ifdef CONFIG_PROC_FS
178 static int IFX_MEI_ProcRead (struct file *, char *, size_t, loff_t *);
179 static ssize_t IFX_MEI_ProcWrite (struct file *, const char *, size_t, loff_t *);
181 #define PROC_ITEMS 11
182 #define MEI_DIRNAME "ifxmips_mei"
184 static struct proc_dir_entry *meidir;
185 static struct file_operations IFX_MEI_ProcOperations = {
186 read:IFX_MEI_ProcRead,
187 write:IFX_MEI_ProcWrite,
189 static reg_entry_t regs[BSP_MAX_DEVICES][PROC_ITEMS]; //total items to be monitored by /proc/mei
190 #define NUM_OF_REG_ENTRY (sizeof(regs[0])/sizeof(reg_entry_t))
191 #endif //CONFIG_PROC_FS
193 void IFX_MEI_ARC_MUX_Test(void);
195 static int adsl_dummy_ledcallback(void);
197 int (*ifx_mei_atm_showtime_enter)(struct port_cell_info *, void *) = NULL;
198 EXPORT_SYMBOL(ifx_mei_atm_showtime_enter);
200 int (*ifx_mei_atm_showtime_exit)(void) = NULL;
201 EXPORT_SYMBOL(ifx_mei_atm_showtime_exit);
203 static int (*g_adsl_ledcallback)(void) = adsl_dummy_ledcallback;
205 static unsigned int g_tx_link_rate[2] = {0};
207 static void *g_xdata_addr = NULL;
209 static u32 *mei_arc_swap_buff = NULL; // holding swap pages
211 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39))
212 extern void ltq_mask_and_ack_irq(unsigned int irq_nr);
213 #define MEI_MASK_AND_ACK_IRQ ltq_mask_and_ack_irq
215 extern void ltq_mask_and_ack_irq(struct irq_data *d);
216 static void inline MEI_MASK_AND_ACK_IRQ(int x)
220 ltq_mask_and_ack_irq(&d);
223 #define MEI_MAJOR 105
224 static int dev_major = MEI_MAJOR;
226 static struct file_operations bsp_mei_operations = {
229 release:IFX_MEI_Release,
231 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36))
232 ioctl:IFX_MEI_UserIoctls,
234 unlocked_ioctl:IFX_MEI_UserIoctls,
238 static DSL_DEV_Device_t dsl_devices[BSP_MAX_DEVICES];
240 static ifx_mei_device_private_t
241 sDanube_Mei_Private[BSP_MAX_DEVICES];
243 static DSL_BSP_EventCallBack_t dsl_bsp_event_callback[DSL_BSP_CB_LAST + 1];
246 * Write a value to register
247 * This function writes a value to danube register
249 * \param ul_address The address to write
250 * \param ul_data The value to write
254 IFX_MEI_LongWordWrite (u32 ul_address, u32 ul_data)
256 IFX_MEI_WRITE_REGISTER_L (ul_data, ul_address);
262 * Write a value to register
263 * This function writes a value to danube register
265 * \param pDev the device pointer
266 * \param ul_address The address to write
267 * \param ul_data The value to write
271 IFX_MEI_LongWordWriteOffset (DSL_DEV_Device_t * pDev, u32 ul_address,
274 IFX_MEI_WRITE_REGISTER_L (ul_data, pDev->base_address + ul_address);
280 * Read the danube register
281 * This function read the value from danube register
283 * \param ul_address The address to write
284 * \param pul_data Pointer to the data
288 IFX_MEI_LongWordRead (u32 ul_address, u32 * pul_data)
290 *pul_data = IFX_MEI_READ_REGISTER_L (ul_address);
296 * Read the danube register
297 * This function read the value from danube register
299 * \param pDev the device pointer
300 * \param ul_address The address to write
301 * \param pul_data Pointer to the data
305 IFX_MEI_LongWordReadOffset (DSL_DEV_Device_t * pDev, u32 ul_address,
308 *pul_data = IFX_MEI_READ_REGISTER_L (pDev->base_address + ul_address);
314 * Write several DWORD datas to ARC memory via ARC DMA interface
315 * This function writes several DWORD datas to ARC memory via DMA interface.
317 * \param pDev the device pointer
318 * \param destaddr The address to write
319 * \param databuff Pointer to the data buffer
320 * \param databuffsize Number of DWORDs to write
321 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
324 static DSL_DEV_MeiError_t
325 IFX_MEI_DMAWrite (DSL_DEV_Device_t * pDev, u32 destaddr,
326 u32 * databuff, u32 databuffsize)
332 return DSL_DEV_MEI_ERR_FAILURE;
334 // Set the write transfer address
335 IFX_MEI_LongWordWriteOffset (pDev, ME_DX_AD, destaddr);
337 // Write the data pushed across DMA
338 while (databuffsize--) {
340 if (destaddr == MEI_TO_ARC_MAILBOX)
341 MEI_HALF_WORD_SWAP (temp);
342 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DX_DATA, temp);
346 return DSL_DEV_MEI_ERR_SUCCESS;
351 * Read several DWORD datas from ARC memory via ARC DMA interface
352 * This function reads several DWORD datas from ARC memory via DMA interface.
354 * \param pDev the device pointer
355 * \param srcaddr The address to read
356 * \param databuff Pointer to the data buffer
357 * \param databuffsize Number of DWORDs to read
358 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
361 static DSL_DEV_MeiError_t
362 IFX_MEI_DMARead (DSL_DEV_Device_t * pDev, u32 srcaddr, u32 * databuff,
369 return DSL_DEV_MEI_ERR_FAILURE;
371 // Set the read transfer address
372 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DX_AD, srcaddr);
374 // Read the data popped across DMA
375 while (databuffsize--) {
376 IFX_MEI_LongWordReadOffset (pDev, (u32) ME_DX_DATA, &temp);
377 if (databuff == (u32 *) DSL_DEV_PRIVATE(pDev)->CMV_RxMsg) // swap half word
378 MEI_HALF_WORD_SWAP (temp);
383 return DSL_DEV_MEI_ERR_SUCCESS;
388 * Switch the ARC control mode
389 * This function switchs the ARC control mode to JTAG mode or MEI mode
391 * \param pDev the device pointer
392 * \param mode The mode want to switch: JTAG_MASTER_MODE or MEI_MASTER_MODE.
396 IFX_MEI_ControlModeSet (DSL_DEV_Device_t * pDev, int mode)
400 IFX_MEI_LongWordReadOffset (pDev, (u32) ME_DBG_MASTER, &temp);
402 case JTAG_MASTER_MODE:
403 temp &= ~(HOST_MSTR);
405 case MEI_MASTER_MODE:
409 IFX_MEI_EMSG ("IFX_MEI_ControlModeSet: unkonwn mode [%d]\n", mode);
412 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_MASTER, temp);
416 * Disable ARC to MEI interrupt
418 * \param pDev the device pointer
422 IFX_MEI_IRQDisable (DSL_DEV_Device_t * pDev)
424 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_MASK, 0x0);
428 * Eable ARC to MEI interrupt
430 * \param pDev the device pointer
434 IFX_MEI_IRQEnable (DSL_DEV_Device_t * pDev)
436 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_MASK, MSGAV_EN);
440 * Poll for transaction complete signal
441 * This function polls and waits for transaction complete signal.
443 * \param pDev the device pointer
447 meiPollForDbgDone (DSL_DEV_Device_t * pDev)
452 while (i < WHILE_DELAY) {
453 IFX_MEI_LongWordReadOffset (pDev, (u32) ME_ARC2ME_STAT, &query);
454 query &= (ARC_TO_MEI_DBG_DONE);
458 if (i == WHILE_DELAY) {
459 IFX_MEI_EMSG ("PollforDbg fail!\n");
462 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_STAT, ARC_TO_MEI_DBG_DONE); // to clear this interrupt
466 * ARC Debug Memory Access for a single DWORD reading.
467 * This function used for direct, address-based access to ARC memory.
469 * \param pDev the device pointer
470 * \param DEC_mode ARC memory space to used
471 * \param address Address to read
472 * \param data Pointer to data
473 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
476 static DSL_DEV_MeiError_t
477 _IFX_MEI_DBGLongWordRead (DSL_DEV_Device_t * pDev, u32 DEC_mode,
478 u32 address, u32 * data)
480 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_DECODE, DEC_mode);
481 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_RD_AD, address);
482 meiPollForDbgDone (pDev);
483 IFX_MEI_LongWordReadOffset (pDev, (u32) ME_DBG_DATA, data);
484 return DSL_DEV_MEI_ERR_SUCCESS;
488 * ARC Debug Memory Access for a single DWORD writing.
489 * This function used for direct, address-based access to ARC memory.
491 * \param pDev the device pointer
492 * \param DEC_mode ARC memory space to used
493 * \param address The address to write
494 * \param data The data to write
495 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
498 static DSL_DEV_MeiError_t
499 _IFX_MEI_DBGLongWordWrite (DSL_DEV_Device_t * pDev, u32 DEC_mode,
500 u32 address, u32 data)
502 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_DECODE, DEC_mode);
503 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_WR_AD, address);
504 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_DATA, data);
505 meiPollForDbgDone (pDev);
506 return DSL_DEV_MEI_ERR_SUCCESS;
510 * ARC Debug Memory Access for writing.
511 * This function used for direct, address-based access to ARC memory.
513 * \param pDev the device pointer
514 * \param destaddr The address to read
515 * \param databuffer Pointer to data
516 * \param databuffsize The number of DWORDs to read
517 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
521 static DSL_DEV_MeiError_t
522 IFX_MEI_DebugWrite (DSL_DEV_Device_t * pDev, u32 destaddr,
523 u32 * databuff, u32 databuffsize)
530 // Open the debug port before DMP memory write
531 IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
533 // For the requested length, write the address and write the data
536 for (i = 0; i < databuffsize; i++) {
538 _IFX_MEI_DBGLongWordWrite (pDev, ME_DBG_DECODE_DMP1_MASK, address, temp);
543 // Close the debug port after DMP memory write
544 IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
546 return DSL_DEV_MEI_ERR_SUCCESS;
550 * ARC Debug Memory Access for reading.
551 * This function used for direct, address-based access to ARC memory.
553 * \param pDev the device pointer
554 * \param srcaddr The address to read
555 * \param databuffer Pointer to data
556 * \param databuffsize The number of DWORDs to read
557 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
560 static DSL_DEV_MeiError_t
561 IFX_MEI_DebugRead (DSL_DEV_Device_t * pDev, u32 srcaddr, u32 * databuff, u32 databuffsize)
568 // Open the debug port before DMP memory read
569 IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
571 // For the requested length, write the address and read the data
574 for (i = 0; i < databuffsize; i++) {
575 _IFX_MEI_DBGLongWordRead (pDev, ME_DBG_DECODE_DMP1_MASK, address, &temp);
581 // Close the debug port after DMP memory read
582 IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
584 return DSL_DEV_MEI_ERR_SUCCESS;
588 * Send a message to ARC MailBox.
589 * This function sends a message to ARC Mailbox via ARC DMA interface.
591 * \param pDev the device pointer
592 * \param msgsrcbuffer Pointer to message.
593 * \param msgsize The number of words to write.
594 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
597 static DSL_DEV_MeiError_t
598 IFX_MEI_MailboxWrite (DSL_DEV_Device_t * pDev, u16 * msgsrcbuffer,
602 u32 arc_mailbox_status = 0x0;
604 DSL_DEV_MeiError_t meiMailboxError = DSL_DEV_MEI_ERR_SUCCESS;
608 IFX_MEI_DMAWrite (pDev, MEI_TO_ARC_MAILBOX, (u32 *) msgsrcbuffer, msgsize / 2);
610 IFX_MEI_DMAWrite (pDev, MEI_TO_ARC_MAILBOXR, (u32 *) (&temp), 1);
612 // Notify arc that mailbox write completed
613 DSL_DEV_PRIVATE(pDev)->cmv_waiting = 1;
614 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ME2ARC_INT, MEI_TO_ARC_MSGAV);
617 while (i < WHILE_DELAY) { // wait for ARC to clear the bit
618 IFX_MEI_LongWordReadOffset (pDev, (u32) ME_ME2ARC_INT, &arc_mailbox_status);
619 if ((arc_mailbox_status & MEI_TO_ARC_MSGAV) != MEI_TO_ARC_MSGAV)
622 if (i == WHILE_DELAY) {
623 IFX_MEI_EMSG (">>> Timeout waiting for ARC to clear MEI_TO_ARC_MSGAV!!!"
624 " MEI_TO_ARC message size = %d DWORDs <<<\n", msgsize/2);
625 meiMailboxError = DSL_DEV_MEI_ERR_FAILURE;
629 return meiMailboxError;
633 * Read a message from ARC MailBox.
634 * This function reads a message from ARC Mailbox via ARC DMA interface.
636 * \param pDev the device pointer
637 * \param msgsrcbuffer Pointer to message.
638 * \param msgsize The number of words to read
639 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
642 static DSL_DEV_MeiError_t
643 IFX_MEI_MailboxRead (DSL_DEV_Device_t * pDev, u16 * msgdestbuffer,
646 DSL_DEV_MeiError_t meiMailboxError = DSL_DEV_MEI_ERR_SUCCESS;
649 IFX_MEI_DMARead (pDev, ARC_TO_MEI_MAILBOX, (u32 *) msgdestbuffer, msgsize / 2);
651 // Notify arc that mailbox read completed
652 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_STAT, ARC_TO_MEI_MSGAV);
654 return meiMailboxError;
658 * Download boot pages to ARC.
659 * This function downloads boot pages to ARC.
661 * \param pDev the device pointer
662 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
665 static DSL_DEV_MeiError_t
666 IFX_MEI_DownloadBootPages (DSL_DEV_Device_t * pDev)
673 ** DMA the boot code page(s)
678 (DSL_DEV_PRIVATE(pDev)->img_hdr-> count); boot_loop++) {
679 if ((DSL_DEV_PRIVATE(pDev)-> img_hdr->page[boot_loop].p_size) & BOOT_FLAG) {
680 page_size = IFX_MEI_GetPage (pDev, boot_loop,
681 GET_PROG, MAXSWAPSIZE,
685 IFX_MEI_DMAWrite (pDev, dest_addr,
690 if ((DSL_DEV_PRIVATE(pDev)-> img_hdr->page[boot_loop].d_size) & BOOT_FLAG) {
691 page_size = IFX_MEI_GetPage (pDev, boot_loop,
692 GET_DATA, MAXSWAPSIZE,
696 IFX_MEI_DMAWrite (pDev, dest_addr,
702 return DSL_DEV_MEI_ERR_SUCCESS;
709 IFX_MEI_FuseInit (DSL_DEV_Device_t * pDev)
712 IFX_MEI_DMAWrite (pDev, IRAM0_BASE, &data, 1);
713 IFX_MEI_DMAWrite (pDev, IRAM0_BASE + 4, &data, 1);
714 IFX_MEI_DMAWrite (pDev, IRAM1_BASE, &data, 1);
715 IFX_MEI_DMAWrite (pDev, IRAM1_BASE + 4, &data, 1);
716 IFX_MEI_DMAWrite (pDev, BRAM_BASE, &data, 1);
717 IFX_MEI_DMAWrite (pDev, BRAM_BASE + 4, &data, 1);
718 IFX_MEI_DMAWrite (pDev, ADSL_DILV_BASE, &data, 1);
719 IFX_MEI_DMAWrite (pDev, ADSL_DILV_BASE + 4, &data, 1);
726 IFX_MEI_FuseProg (DSL_DEV_Device_t * pDev)
728 u32 reg_data, fuse_value;
731 IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, ®_data);
732 while ((reg_data & 0x10000000) == 0) {
733 IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, ®_data);
735 /* 0x4000 translate to about 16 ms@111M, so should be enough */
739 // STEP a: Prepare memory for external accesses
740 // Write fuse_en bit24
741 IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, ®_data);
742 IFX_MEI_LongWordWrite ((u32) LTQ_RCU_RST, reg_data | (1 << 24));
744 IFX_MEI_FuseInit (pDev);
745 for (i = 0; i < 4; i++) {
746 IFX_MEI_LongWordRead ((u32) (LTQ_FUSE_BASE) + i * 4, &fuse_value);
747 switch (fuse_value & 0xF0000) {
749 reg_data = ((fuse_value & RX_DILV_ADDR_BIT_MASK) |
750 (RX_DILV_ADDR_BIT_MASK + 0x1));
751 IFX_MEI_DMAWrite (pDev, ADSL_DILV_BASE, ®_data, 1);
754 reg_data = ((fuse_value & RX_DILV_ADDR_BIT_MASK) |
755 (RX_DILV_ADDR_BIT_MASK + 0x1));
756 IFX_MEI_DMAWrite (pDev, ADSL_DILV_BASE + 4, ®_data, 1);
759 reg_data = ((fuse_value & IRAM0_ADDR_BIT_MASK) |
760 (IRAM0_ADDR_BIT_MASK + 0x1));
761 IFX_MEI_DMAWrite (pDev, IRAM0_BASE, ®_data, 1);
764 reg_data = ((fuse_value & IRAM0_ADDR_BIT_MASK) |
765 (IRAM0_ADDR_BIT_MASK + 0x1));
766 IFX_MEI_DMAWrite (pDev, IRAM0_BASE + 4, ®_data, 1);
769 reg_data = ((fuse_value & IRAM1_ADDR_BIT_MASK) |
770 (IRAM1_ADDR_BIT_MASK + 0x1));
771 IFX_MEI_DMAWrite (pDev, IRAM1_BASE, ®_data, 1);
774 reg_data = ((fuse_value & IRAM1_ADDR_BIT_MASK) |
775 (IRAM1_ADDR_BIT_MASK + 0x1));
776 IFX_MEI_DMAWrite (pDev, IRAM1_BASE + 4, ®_data, 1);
779 reg_data = ((fuse_value & BRAM_ADDR_BIT_MASK) |
780 (BRAM_ADDR_BIT_MASK + 0x1));
781 IFX_MEI_DMAWrite (pDev, BRAM_BASE, ®_data, 1);
784 reg_data = ((fuse_value & BRAM_ADDR_BIT_MASK) |
785 (BRAM_ADDR_BIT_MASK + 0x1));
786 IFX_MEI_DMAWrite (pDev, BRAM_BASE + 4, ®_data, 1);
788 default: // PPE efuse
792 IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, ®_data);
793 IFX_MEI_LongWordWrite ((u32) LTQ_RCU_RST, reg_data & ~(1 << 24));
794 IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, ®_data);
799 * This function enables DFE Clock
801 * \param pDev the device pointer
802 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
805 static DSL_DEV_MeiError_t
806 IFX_MEI_EnableCLK (DSL_DEV_Device_t * pDev)
808 u32 arc_debug_data = 0;
809 IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
810 //enable ac_clk signal
811 _IFX_MEI_DBGLongWordRead (pDev, ME_DBG_DECODE_DMP1_MASK,
812 CRI_CCR0, &arc_debug_data);
813 arc_debug_data |= ACL_CLK_MODE_ENABLE;
814 _IFX_MEI_DBGLongWordWrite (pDev, ME_DBG_DECODE_DMP1_MASK,
815 CRI_CCR0, arc_debug_data);
816 IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
817 return DSL_DEV_MEI_ERR_SUCCESS;
822 * This function halts the ARC.
824 * \param pDev the device pointer
825 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
828 static DSL_DEV_MeiError_t
829 IFX_MEI_HaltArc (DSL_DEV_Device_t * pDev)
831 u32 arc_debug_data = 0x0;
833 // Switch arc control from JTAG mode to MEI mode
834 IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
835 _IFX_MEI_DBGLongWordRead (pDev, MEI_DEBUG_DEC_AUX_MASK,
836 ARC_DEBUG, &arc_debug_data);
837 arc_debug_data |= ARC_DEBUG_HALT;
838 _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK,
839 ARC_DEBUG, arc_debug_data);
840 // Switch arc control from MEI mode to JTAG mode
841 IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
845 return DSL_DEV_MEI_ERR_SUCCESS;
850 * This function runs the ARC.
852 * \param pDev the device pointer
853 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
856 static DSL_DEV_MeiError_t
857 IFX_MEI_RunArc (DSL_DEV_Device_t * pDev)
859 u32 arc_debug_data = 0x0;
861 // Switch arc control from JTAG mode to MEI mode- write '1' to bit0
862 IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
863 _IFX_MEI_DBGLongWordRead (pDev, MEI_DEBUG_DEC_AUX_MASK,
864 AUX_STATUS, &arc_debug_data);
866 // Write debug data reg with content ANDd with 0xFDFFFFFF (halt bit cleared)
867 arc_debug_data &= ~ARC_AUX_HALT;
868 _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK,
869 AUX_STATUS, arc_debug_data);
871 // Switch arc control from MEI mode to JTAG mode- write '0' to bit0
872 IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
873 // Enable mask for arc codeswap interrupts
874 IFX_MEI_IRQEnable (pDev);
876 return DSL_DEV_MEI_ERR_SUCCESS;
882 * This function resets the ARC.
884 * \param pDev the device pointer
885 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
888 static DSL_DEV_MeiError_t
889 IFX_MEI_ResetARC (DSL_DEV_Device_t * pDev)
891 u32 arc_debug_data = 0;
893 IFX_MEI_HaltArc (pDev);
895 IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, &arc_debug_data);
896 IFX_MEI_LongWordWrite ((u32) LTQ_RCU_RST,
897 arc_debug_data | LTQ_RCU_RST_REQ_DFE | LTQ_RCU_RST_REQ_AFE);
900 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_RST_CTRL, MEI_SOFT_RESET);
901 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_RST_CTRL, 0);
903 IFX_MEI_IRQDisable (pDev);
905 IFX_MEI_EnableCLK (pDev);
909 *(unsigned long *) (BSP_PPE32_SRST) = 0xC30;
910 *(unsigned long *) (BSP_PPE32_SRST) = 0xFFF;
913 DSL_DEV_PRIVATE(pDev)->modem_ready = 0;
915 return DSL_DEV_MEI_ERR_SUCCESS;
919 DSL_BSP_Showtime (DSL_DEV_Device_t * dev, DSL_uint32_t rate_fast, DSL_uint32_t rate_intl)
921 struct port_cell_info port_cell = {0};
923 IFX_MEI_EMSG ("Datarate US intl = %d, fast = %d\n", (int)rate_intl,
927 g_tx_link_rate[0] = rate_fast / (53 * 8);
929 g_tx_link_rate[1] = rate_intl / (53 * 8);
931 if ( g_tx_link_rate[0] == 0 && g_tx_link_rate[1] == 0 ) {
932 IFX_MEI_EMSG ("Got rate fail.\n");
935 if ( ifx_mei_atm_showtime_enter )
937 port_cell.port_num = 2;
938 port_cell.tx_link_rate[0] = g_tx_link_rate[0];
939 port_cell.tx_link_rate[1] = g_tx_link_rate[1];
940 ifx_mei_atm_showtime_enter(&port_cell, g_xdata_addr);
944 IFX_MEI_EMSG("no hookup from ATM driver to set cell rate\n");
947 return DSL_DEV_MEI_ERR_SUCCESS;
951 * Reset/halt/run the DFE.
952 * This function provide operations to reset/halt/run the DFE.
954 * \param pDev the device pointer
955 * \param mode which operation want to do
956 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
959 static DSL_DEV_MeiError_t
960 IFX_MEI_CpuModeSet (DSL_DEV_Device_t *pDev,
961 DSL_DEV_CpuMode_t mode)
963 DSL_DEV_MeiError_t err_ret = DSL_DEV_MEI_ERR_FAILURE;
966 err_ret = IFX_MEI_HaltArc (pDev);
969 err_ret = IFX_MEI_RunArc (pDev);
972 err_ret = IFX_MEI_ResetARC (pDev);
981 * Accress DFE memory.
982 * This function provide a way to access DFE memory;
984 * \param pDev the device pointer
985 * \param type read or write
986 * \param destaddr destination address
987 * \param databuff pointer to hold data
988 * \param databuffsize size want to read/write
989 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
993 DSL_BSP_MemoryDebugAccess (DSL_DEV_Device_t * pDev,
994 DSL_BSP_MemoryAccessType_t type,
995 DSL_uint32_t destaddr, DSL_uint32_t *databuff,
996 DSL_uint32_t databuffsize)
998 DSL_DEV_MeiError_t meierr = DSL_DEV_MEI_ERR_SUCCESS;
1000 case DSL_BSP_MEMORY_READ:
1001 meierr = IFX_MEI_DebugRead (pDev, (u32)destaddr, (u32*)databuff, (u32)databuffsize);
1003 case DSL_BSP_MEMORY_WRITE:
1004 meierr = IFX_MEI_DebugWrite (pDev, (u32)destaddr, (u32*)databuff, (u32)databuffsize);
1007 return DSL_DEV_MEI_ERR_SUCCESS;
1011 * Download boot code to ARC.
1012 * This function downloads boot code to ARC.
1014 * \param pDev the device pointer
1015 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
1018 static DSL_DEV_MeiError_t
1019 IFX_MEI_DownloadBootCode (DSL_DEV_Device_t *pDev)
1021 IFX_MEI_IRQDisable (pDev);
1023 IFX_MEI_EnableCLK (pDev);
1025 IFX_MEI_FuseProg (pDev); //program fuse rar
1027 IFX_MEI_DownloadBootPages (pDev);
1029 return DSL_DEV_MEI_ERR_SUCCESS;
1033 * Enable Jtag debugger interface
1034 * This function setups mips gpio to enable jtag debugger
1036 * \param pDev the device pointer
1037 * \param enable enable or disable
1038 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
1041 static DSL_DEV_MeiError_t
1042 IFX_MEI_ArcJtagEnable (DSL_DEV_Device_t *dev, int enable)
1049 //reserve gpio 9, 10, 11, 14, 19 for ARC JTAG
1050 ifxmips_port_reserve_pin (0, 9);
1051 ifxmips_port_reserve_pin (0, 10);
1052 ifxmips_port_reserve_pin (0, 11);
1053 ifxmips_port_reserve_pin (0, 14);
1054 ifxmips_port_reserve_pin (1, 3);
1056 ifxmips_port_set_dir_in(0, 11);
1057 ifxmips_port_clear_altsel0(0, 11);
1058 ifxmips_port_clear_altsel1(0, 11);
1059 ifxmips_port_set_open_drain(0, 11);
1061 IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, ®_data);
1062 IFX_MEI_LongWordWrite ((u32) LTQ_RCU_RST, reg_data | LTQ_RCU_RST_REQ_ARC_JTAG);
1070 return DSL_DEV_MEI_ERR_FAILURE;
1073 return DSL_DEV_MEI_ERR_SUCCESS;
1077 * Enable DFE to MIPS interrupt
1078 * This function enable DFE to MIPS interrupt
1080 * \param pDev the device pointer
1081 * \param enable enable or disable
1082 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
1085 static DSL_DEV_MeiError_t
1086 IFX_MEI_AdslMailboxIRQEnable (DSL_DEV_Device_t *pDev, int enable)
1088 DSL_DEV_MeiError_t meierr;
1091 meierr = DSL_DEV_MEI_ERR_SUCCESS;
1092 IFX_MEI_IRQDisable (pDev);
1095 IFX_MEI_IRQEnable (pDev);
1096 meierr = DSL_DEV_MEI_ERR_SUCCESS;
1099 meierr = DSL_DEV_MEI_ERR_FAILURE;
1107 * Get the modem status
1108 * This function return the modem status
1110 * \param pDev the device pointer
1111 * \return 1: modem ready 0: not ready
1115 IFX_MEI_IsModemReady (DSL_DEV_Device_t * pDev)
1117 return DSL_DEV_PRIVATE(pDev)->modem_ready;
1121 DSL_BSP_AdslLedInit (DSL_DEV_Device_t * dev,
1122 DSL_DEV_LedId_t led_number,
1123 DSL_DEV_LedType_t type,
1124 DSL_DEV_LedHandler_t handler)
1127 struct led_config_param param;
1128 if (led_number == DSL_LED_LINK_ID && type == DSL_LED_LINK_TYPE && handler == /*DSL_LED_HD_CPU*/DSL_LED_HD_FW) {
1129 param.operation_mask = CONFIG_OPERATION_UPDATE_SOURCE;
1131 param.source = 0x01;
1132 // bsp_led_config (¶m);
1134 } else if (led_number == DSL_LED_DATA_ID && type == DSL_LED_DATA_TYPE && (handler == DSL_LED_HD_FW)) {
1135 param.operation_mask = CONFIG_OPERATION_UPDATE_SOURCE;
1137 param.source = 0x02;
1138 // bsp_led_config (¶m);
1141 return DSL_DEV_MEI_ERR_SUCCESS;
1145 DSL_BSP_AdslLedSet (DSL_DEV_Device_t * dev, DSL_DEV_LedId_t led_number, DSL_DEV_LedMode_t mode)
1147 printk(KERN_INFO "[%s %d]: mode = %#x, led_number = %d\n", __func__, __LINE__, mode, led_number);
1150 switch (led_number) {
1151 case DSL_LED_LINK_ID:
1152 #ifdef CONFIG_BSP_LED
1153 bsp_led_set_blink (1, 0);
1154 bsp_led_set_data (1, 0);
1157 case DSL_LED_DATA_ID:
1158 #ifdef CONFIG_BSP_LED
1159 bsp_led_set_blink (0, 0);
1160 bsp_led_set_data (0, 0);
1166 switch (led_number) {
1167 case DSL_LED_LINK_ID:
1168 #ifdef CONFIG_BSP_LED
1169 bsp_led_set_blink (1, 1); // data
1172 case DSL_LED_DATA_ID:
1173 #ifdef CONFIG_BSP_LED
1174 bsp_led_set_blink (0, 1); // data
1180 switch (led_number) {
1181 case DSL_LED_LINK_ID:
1182 #ifdef CONFIG_BSP_LED
1183 bsp_led_set_blink (1, 0);
1184 bsp_led_set_data (1, 1);
1187 case DSL_LED_DATA_ID:
1188 #ifdef CONFIG_BSP_LED
1189 bsp_led_set_blink (0, 0);
1190 bsp_led_set_data (0, 1);
1196 return DSL_DEV_MEI_ERR_SUCCESS;
1202 * Compose a message.
1203 * This function compose a message from opcode, group, address, index, size, and data
1205 * \param opcode The message opcode
1206 * \param group The message group number
1207 * \param address The message address.
1208 * \param index The message index.
1209 * \param size The number of words to read/write.
1210 * \param data The pointer to data.
1211 * \param CMVMSG The pointer to message buffer.
1215 makeCMV (u8 opcode, u8 group, u16 address, u16 index, int size, u16 * data, u16 *CMVMSG)
1217 memset (CMVMSG, 0, MSG_LENGTH * 2);
1218 CMVMSG[0] = (opcode << 4) + (size & 0xf);
1219 CMVMSG[1] = (((index == 0) ? 0 : 1) << 7) + (group & 0x7f);
1220 CMVMSG[2] = address;
1222 if (opcode == H2D_CMV_WRITE)
1223 memcpy (CMVMSG + 4, data, size * 2);
1228 * Send a message to ARC and read the response
1229 * This function sends a message to arc, waits the response, and reads the responses.
1231 * \param pDev the device pointer
1232 * \param request Pointer to the request
1233 * \param reply Wait reply or not.
1234 * \param response Pointer to the response
1235 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
1239 DSL_BSP_SendCMV (DSL_DEV_Device_t * pDev, u16 * request, int reply, u16 * response) // write cmv to arc, if reply needed, wait for reply
1241 DSL_DEV_MeiError_t meierror;
1242 #if defined(BSP_PORT_RTEMS)
1243 int delay_counter = 0;
1246 if (MEI_MUTEX_LOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema))
1247 return -ERESTARTSYS;
1249 DSL_DEV_PRIVATE(pDev)->cmv_reply = reply;
1250 memset (DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, 0,
1251 sizeof (DSL_DEV_PRIVATE(pDev)->
1253 DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
1255 meierror = IFX_MEI_MailboxWrite (pDev, request, MSG_LENGTH);
1257 if (meierror != DSL_DEV_MEI_ERR_SUCCESS) {
1258 DSL_DEV_PRIVATE(pDev)->cmv_waiting = 0;
1259 DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
1260 IFX_MEI_EMSG ("MailboxWrite Fail!\n");
1261 IFX_MEI_EMSG ("Resetting ARC...\n");
1262 IFX_MEI_ResetARC(pDev);
1263 MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
1267 DSL_DEV_PRIVATE(pDev)->cmv_count++;
1270 if (DSL_DEV_PRIVATE(pDev)->cmv_reply ==
1272 MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
1273 return DSL_DEV_MEI_ERR_SUCCESS;
1276 #if !defined(BSP_PORT_RTEMS)
1277 if (DSL_DEV_PRIVATE(pDev)->arcmsgav == 0)
1278 MEI_WAIT_EVENT_TIMEOUT (DSL_DEV_PRIVATE(pDev)->wait_queue_arcmsgav, CMV_TIMEOUT);
1280 while (DSL_DEV_PRIVATE(pDev)->arcmsgav == 0 && delay_counter < CMV_TIMEOUT / 5) {
1286 DSL_DEV_PRIVATE(pDev)->cmv_waiting = 0;
1287 if (DSL_DEV_PRIVATE(pDev)->arcmsgav == 0) { //CMV_timeout
1288 DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
1289 IFX_MEI_EMSG ("\%s: DSL_DEV_MEI_ERR_MAILBOX_TIMEOUT\n",
1291 MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
1292 return DSL_DEV_MEI_ERR_MAILBOX_TIMEOUT;
1295 DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
1296 DSL_DEV_PRIVATE(pDev)->
1298 memcpy (response, DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, MSG_LENGTH * 2);
1299 MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
1300 return DSL_DEV_MEI_ERR_SUCCESS;
1302 MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
1303 return DSL_DEV_MEI_ERR_SUCCESS;
1307 * Reset the ARC, download boot codes, and run the ARC.
1308 * This function resets the ARC, downloads boot codes to ARC, and runs the ARC.
1310 * \param pDev the device pointer
1311 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
1314 static DSL_DEV_MeiError_t
1315 IFX_MEI_RunAdslModem (DSL_DEV_Device_t *pDev)
1317 int nSize = 0, idx = 0;
1318 uint32_t im0_register, im2_register;
1319 // DSL_DEV_WinHost_Message_t m;
1321 if (mei_arc_swap_buff == NULL) {
1323 (u32 *) kmalloc (MAXSWAPSIZE * 4, GFP_KERNEL);
1324 if (mei_arc_swap_buff == NULL) {
1325 IFX_MEI_EMSG (">>> malloc fail for codeswap buff!!! <<<\n");
1326 return DSL_DEV_MEI_ERR_FAILURE;
1328 IFX_MEI_DMSG("allocate %dKB swap buff memory at: 0x%p\n", ksize(mei_arc_swap_buff)/1024, mei_arc_swap_buff);
1331 DSL_DEV_PRIVATE(pDev)->img_hdr =
1332 (ARC_IMG_HDR *) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[0].address;
1333 if ((DSL_DEV_PRIVATE(pDev)->img_hdr->
1334 count) * sizeof (ARC_SWP_PAGE_HDR) > SDRAM_SEGMENT_SIZE) {
1335 IFX_MEI_EMSG ("firmware header size is bigger than 64K segment size\n");
1336 return DSL_DEV_MEI_ERR_FAILURE;
1339 for (idx = 0; idx < MAX_BAR_REGISTERS; idx++) {
1340 nSize += DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].nCopy;
1343 DSL_DEV_PRIVATE(pDev)->image_size) {
1344 IFX_MEI_EMSG ("Firmware download is not completed. Please download firmware again!\n");
1345 return DSL_DEV_MEI_ERR_FAILURE;
1350 IFX_MEI_ResetARC (pDev);
1351 IFX_MEI_HaltArc (pDev);
1352 IFX_MEI_BarUpdate (pDev, DSL_DEV_PRIVATE(pDev)->nBar);
1354 //IFX_MEI_DMSG("Starting to meiDownloadBootCode\n");
1356 IFX_MEI_DownloadBootCode (pDev);
1358 im0_register = (*LTQ_ICU_IM0_IER) & (1 << 20);
1359 im2_register = (*LTQ_ICU_IM2_IER) & (1 << 20);
1361 #ifdef CONFIG_SOC_AMAZON_SE
1362 #define IFXMIPS_USB_OC_INT0 (INT_NUM_IM4_IRL0 + 23)
1363 disable_irq (IFXMIPS_USB_OC_INT0);
1364 // disable_irq (IFXMIPS_USB_OC_INT2);
1365 #elif defined(CONFIG_SOC_AR9)
1366 #define IFXMIPS_USB_OC_INT0 (INT_NUM_IM4_IRL1 + 28)
1367 disable_irq (IFXMIPS_USB_OC_INT0);
1368 // disable_irq (IFXMIPS_USB_OC_INT2);
1369 #elif defined(CONFIG_SOC_XWAY)
1370 disable_irq (LTQ_USB_OC_INT);
1374 disable_irq (pDev->nIrq[IFX_DYING_GASP]);
1376 IFX_MEI_RunArc (pDev);
1378 MEI_WAIT_EVENT_TIMEOUT (DSL_DEV_PRIVATE(pDev)->wait_queue_modemready, 1000);
1380 #ifdef CONFIG_SOC_AMAZON_SE
1381 MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT0);
1382 // MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT2);
1383 #elif defined(CONFIG_SOC_AR9)
1384 MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT0);
1385 // MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT2);
1386 #elif defined(CONFIG_SOC_XWAY)
1387 MEI_MASK_AND_ACK_IRQ (LTQ_USB_OC_INT);
1391 MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DYING_GASP]);
1394 enable_irq(pDev->nIrq[IFX_DYING_GASP]);
1395 *LTQ_ICU_IM0_IER |= im0_register;
1396 *LTQ_ICU_IM2_IER |= im2_register;
1398 if (DSL_DEV_PRIVATE(pDev)->modem_ready != 1) {
1399 IFX_MEI_EMSG ("Modem failed to be ready!\n");
1400 return DSL_DEV_MEI_ERR_FAILURE;
1402 IFX_MEI_DMSG("Modem is ready.\n");
1403 return DSL_DEV_MEI_ERR_SUCCESS;
1408 * Get the page's data pointer
1409 * This function caculats the data address from the firmware header.
1411 * \param pDev the device pointer
1412 * \param Page The page number.
1413 * \param data Data page or program page.
1414 * \param MaxSize The maximum size to read.
1415 * \param Buffer Pointer to data.
1416 * \param Dest Pointer to the destination address.
1417 * \return The number of bytes to read.
1421 IFX_MEI_GetPage (DSL_DEV_Device_t * pDev, u32 Page, u32 data,
1422 u32 MaxSize, u32 * Buffer, u32 * Dest)
1427 u32 idx, offset, nBar = 0;
1429 if (Page > DSL_DEV_PRIVATE(pDev)->img_hdr->count)
1432 ** Get program or data size, depending on "data" flag
1434 size = (data == GET_DATA) ? (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].d_size) :
1435 (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].p_size);
1436 size &= BOOT_FLAG_MASK; // Clear boot bit!
1443 ** Get program or data offset, depending on "data" flag
1445 i = data ? (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].d_offset) :
1446 (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].p_offset);
1449 ** Copy data/program to buffer
1452 idx = i / SDRAM_SEGMENT_SIZE;
1453 offset = i % SDRAM_SEGMENT_SIZE;
1454 p = (u32 *) ((u8 *) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].address + offset);
1456 for (i = 0; i < size; i++) {
1457 if (offset + i * 4 - (nBar * SDRAM_SEGMENT_SIZE) >= SDRAM_SEGMENT_SIZE) {
1460 p = (u32 *) ((u8 *) KSEG1ADDR ((u32)DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].address));
1466 ** Pass back data/program destination address
1468 *Dest = data ? (DSL_DEV_PRIVATE(pDev)-> img_hdr->page[Page].d_dest) :
1469 (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].p_dest);
1475 * Free the memory for ARC firmware
1477 * \param pDev the device pointer
1478 * \param type Free all memory or free the unused memory after showtime
1481 const char *free_str[4] = {"Invalid", "Free_Reload", "Free_Showtime", "Free_All"};
1483 IFX_MEI_DFEMemoryFree (DSL_DEV_Device_t * pDev, int type)
1486 smmu_mem_info_t *adsl_mem_info =
1487 DSL_DEV_PRIVATE(pDev)->adsl_mem_info;
1489 for (idx = 0; idx < MAX_BAR_REGISTERS; idx++) {
1490 if (type == FREE_ALL ||adsl_mem_info[idx].type == type) {
1491 if (adsl_mem_info[idx].size > 0) {
1492 IFX_MEI_DMSG ("Freeing memory %p (%s)\n", adsl_mem_info[idx].org_address, free_str[adsl_mem_info[idx].type]);
1493 if ( idx == XDATA_REGISTER ) {
1494 g_xdata_addr = NULL;
1495 if ( ifx_mei_atm_showtime_exit )
1496 ifx_mei_atm_showtime_exit();
1498 kfree (adsl_mem_info[idx].org_address);
1499 adsl_mem_info[idx].org_address = 0;
1500 adsl_mem_info[idx].address = 0;
1501 adsl_mem_info[idx].size = 0;
1502 adsl_mem_info[idx].type = 0;
1503 adsl_mem_info[idx].nCopy = 0;
1508 if(mei_arc_swap_buff != NULL){
1509 IFX_MEI_DMSG("free %dKB swap buff memory at: 0x%p\n", ksize(mei_arc_swap_buff)/1024, mei_arc_swap_buff);
1510 kfree(mei_arc_swap_buff);
1511 mei_arc_swap_buff=NULL;
1517 IFX_MEI_DFEMemoryAlloc (DSL_DEV_Device_t * pDev, long size)
1519 unsigned long mem_ptr;
1520 char *org_mem_ptr = NULL;
1522 long total_size = 0;
1524 smmu_mem_info_t *adsl_mem_info =
1525 ((ifx_mei_device_private_t *) pDev->pPriv)->adsl_mem_info;
1526 // DSL_DEV_PRIVATE(pDev)->adsl_mem_info;
1527 int allocate_size = SDRAM_SEGMENT_SIZE;
1529 IFX_MEI_DMSG("image_size = %ld\n", size);
1531 for (idx = 0; size > 0 && idx < MAX_BAR_REGISTERS; idx++) {
1532 // skip bar15 for XDATA usage.
1533 if (idx == XDATA_REGISTER)
1536 if (size < SDRAM_SEGMENT_SIZE) {
1537 allocate_size = size;
1538 if (allocate_size < 1024)
1539 allocate_size = 1024;
1542 if (idx == (MAX_BAR_REGISTERS - 1))
1543 allocate_size = size;
1545 allocate_size = SDRAM_SEGMENT_SIZE;
1546 org_mem_ptr = kmalloc (allocate_size + 1024, GFP_KERNEL);
1547 if (org_mem_ptr == NULL) {
1548 IFX_MEI_EMSG ("%d: kmalloc %d bytes memory fail!\n", idx, allocate_size);
1550 goto allocate_error;
1552 mem_ptr = (unsigned long) (org_mem_ptr + 1023) & ~(1024 -1);
1553 adsl_mem_info[idx].address = (char *) mem_ptr;
1554 adsl_mem_info[idx].org_address = org_mem_ptr;
1555 adsl_mem_info[idx].size = allocate_size;
1556 size -= allocate_size;
1557 total_size += allocate_size;
1560 IFX_MEI_EMSG ("Image size is too large!\n");
1562 goto allocate_error;
1568 IFX_MEI_DFEMemoryFree (pDev, FREE_ALL);
1573 * Program the BAR registers
1575 * \param pDev the device pointer
1576 * \param nTotalBar The number of bar to program.
1580 IFX_MEI_BarUpdate (DSL_DEV_Device_t * pDev, int nTotalBar)
1583 smmu_mem_info_t *adsl_mem_info =
1584 DSL_DEV_PRIVATE(pDev)->adsl_mem_info;
1586 for (idx = 0; idx < nTotalBar; idx++) {
1587 //skip XDATA register
1588 if (idx == XDATA_REGISTER)
1590 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XMEM_BAR_BASE + idx * 4,
1591 (((uint32_t) adsl_mem_info[idx].address) & 0x0FFFFFFF));
1593 for (idx = nTotalBar; idx < MAX_BAR_REGISTERS; idx++) {
1594 if (idx == XDATA_REGISTER)
1596 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XMEM_BAR_BASE + idx * 4,
1597 (((uint32_t)adsl_mem_info[nTotalBar - 1].address) & 0x0FFFFFFF));
1598 /* These are for /proc/danube_mei/meminfo purpose */
1599 adsl_mem_info[idx].address = adsl_mem_info[nTotalBar - 1].address;
1600 adsl_mem_info[idx].org_address = adsl_mem_info[nTotalBar - 1].org_address;
1601 adsl_mem_info[idx].size = 0; /* Prevent it from being freed */
1604 g_xdata_addr = adsl_mem_info[XDATA_REGISTER].address;
1605 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XMEM_BAR_BASE + XDATA_REGISTER * 4,
1606 (((uint32_t) adsl_mem_info [XDATA_REGISTER].address) & 0x0FFFFFFF));
1607 // update MEI_XDATA_BASE_SH
1608 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XDATA_BASE_SH,
1609 ((unsigned long)adsl_mem_info[XDATA_REGISTER].address) & 0x0FFFFFFF);
1611 return DSL_DEV_MEI_ERR_SUCCESS;
1614 /* This copies the firmware from secondary storage to 64k memory segment in SDRAM */
1616 DSL_BSP_FWDownload (DSL_DEV_Device_t * pDev, const char *buf,
1617 unsigned long size, long *loff, long *current_offset)
1619 ARC_IMG_HDR img_hdr_tmp;
1620 smmu_mem_info_t *adsl_mem_info = DSL_DEV_PRIVATE(pDev)->adsl_mem_info;
1622 size_t nRead = 0, nCopy = 0;
1624 ssize_t retval = -ENOMEM;
1630 if (size < sizeof (img_hdr_tmp)) {
1631 IFX_MEI_EMSG ("Firmware size is too small!\n");
1634 copy_from_user ((char *) &img_hdr_tmp, buf, sizeof (img_hdr_tmp));
1635 // header of image_size and crc are not included.
1636 DSL_DEV_PRIVATE(pDev)->image_size = le32_to_cpu (img_hdr_tmp.size) + 8;
1638 if (DSL_DEV_PRIVATE(pDev)->image_size > 1024 * 1024) {
1639 IFX_MEI_EMSG ("Firmware size is too large!\n");
1642 // check if arc is halt
1643 IFX_MEI_ResetARC (pDev);
1644 IFX_MEI_HaltArc (pDev);
1646 IFX_MEI_DFEMemoryFree (pDev, FREE_ALL); //free all
1648 retval = IFX_MEI_DFEMemoryAlloc (pDev, DSL_DEV_PRIVATE(pDev)->image_size);
1650 IFX_MEI_EMSG ("Error: No memory space left.\n");
1653 for (idx = 0; idx < retval; idx++) {
1654 //skip XDATA register
1655 if (idx == XDATA_REGISTER)
1657 if (idx * SDRAM_SEGMENT_SIZE < le32_to_cpu (img_hdr_tmp.page[0].p_offset))
1658 adsl_mem_info[idx].type = FREE_RELOAD;
1660 adsl_mem_info[idx].type = FREE_SHOWTIME;
1662 DSL_DEV_PRIVATE(pDev)->nBar = retval;
1664 DSL_DEV_PRIVATE(pDev)->img_hdr =
1665 (ARC_IMG_HDR *) adsl_mem_info[0].address;
1667 adsl_mem_info[XDATA_REGISTER].org_address = kmalloc (SDRAM_SEGMENT_SIZE + 1024, GFP_KERNEL);
1668 adsl_mem_info[XDATA_REGISTER].address =
1669 (char *) ((unsigned long) (adsl_mem_info[XDATA_REGISTER].org_address + 1023) & 0xFFFFFC00);
1671 adsl_mem_info[XDATA_REGISTER].size = SDRAM_SEGMENT_SIZE;
1673 if (adsl_mem_info[XDATA_REGISTER].address == NULL) {
1674 IFX_MEI_EMSG ("kmalloc memory fail!\n");
1678 adsl_mem_info[XDATA_REGISTER].type = FREE_RELOAD;
1679 IFX_MEI_DMSG("-> IFX_MEI_BarUpdate()\n");
1680 IFX_MEI_BarUpdate (pDev, (DSL_DEV_PRIVATE(pDev)->nBar));
1682 else if (DSL_DEV_PRIVATE(pDev)-> image_size == 0) {
1683 IFX_MEI_EMSG ("Error: Firmware size=0! \n");
1688 while (nRead < size) {
1689 long offset = ((long) (*loff) + nRead) % SDRAM_SEGMENT_SIZE;
1690 idx = (((long) (*loff)) + nRead) / SDRAM_SEGMENT_SIZE;
1691 mem_ptr = (char *) KSEG1ADDR ((unsigned long) (adsl_mem_info[idx].address) + offset);
1692 if ((size - nRead + offset) > SDRAM_SEGMENT_SIZE)
1693 nCopy = SDRAM_SEGMENT_SIZE - offset;
1695 nCopy = size - nRead;
1696 copy_from_user (mem_ptr, buf + nRead, nCopy);
1697 for (offset = 0; offset < (nCopy / 4); offset++) {
1698 ((unsigned long *) mem_ptr)[offset] = le32_to_cpu (((unsigned long *) mem_ptr)[offset]);
1701 adsl_mem_info[idx].nCopy += nCopy;
1705 *current_offset = size;
1706 return DSL_DEV_MEI_ERR_SUCCESS;
1708 IFX_MEI_DFEMemoryFree (pDev, FREE_ALL);
1709 return DSL_DEV_MEI_ERR_FAILURE;
1712 * Register a callback event.
1714 * -1 if the event already has a callback function registered.
1717 int DSL_BSP_EventCBRegister(DSL_BSP_EventCallBack_t *p)
1720 IFX_MEI_EMSG("Invalid parameter!\n");
1723 if (p->event > DSL_BSP_CB_LAST || p->event < DSL_BSP_CB_FIRST) {
1724 IFX_MEI_EMSG("Invalid Event %d\n", p->event);
1727 if (dsl_bsp_event_callback[p->event].function) {
1728 IFX_MEI_EMSG("Event %d already has a callback function registered!\n", p->event);
1731 dsl_bsp_event_callback[p->event].function = p->function;
1732 dsl_bsp_event_callback[p->event].event = p->event;
1733 dsl_bsp_event_callback[p->event].pData = p->pData;
1737 int DSL_BSP_EventCBUnregister(DSL_BSP_EventCallBack_t *p)
1740 IFX_MEI_EMSG("Invalid parameter!\n");
1743 if (p->event > DSL_BSP_CB_LAST || p->event < DSL_BSP_CB_FIRST) {
1744 IFX_MEI_EMSG("Invalid Event %d\n", p->event);
1747 if (dsl_bsp_event_callback[p->event].function) {
1748 IFX_MEI_EMSG("Unregistering Event %d...\n", p->event);
1749 dsl_bsp_event_callback[p->event].function = NULL;
1750 dsl_bsp_event_callback[p->event].pData = NULL;
1752 IFX_MEI_EMSG("Event %d is not registered!\n", p->event);
1759 * MEI Dying Gasp interrupt handler
1763 * \param regs Pointer to the structure of danube mips registers
1766 static irqreturn_t IFX_MEI_Dying_Gasp_IrqHandle (int int1, void *void0)
1768 DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) void0;
1769 DSL_BSP_CB_Type_t event;
1772 IFX_MEI_EMSG("Error: Got Interrupt but pDev is NULL!!!!\n");
1775 disable_irq (pDev->nIrq[IFX_DYING_GASP]);
1777 disable_irq_nosync(pDev->nIrq[IFX_DYING_GASP]);
1779 event = DSL_BSP_CB_DYING_GASP;
1781 if (dsl_bsp_event_callback[event].function)
1782 (*dsl_bsp_event_callback[event].function)(pDev, event, dsl_bsp_event_callback[event].pData);
1784 #ifdef CONFIG_USE_EMULATOR
1785 IFX_MEI_EMSG("Dying Gasp! Shutting Down... (Work around for Amazon-S Venus emulator)\n");
1787 IFX_MEI_EMSG("Dying Gasp! Shutting Down...\n");
1788 // kill_proc (1, SIGINT, 1); /* Ask init to reboot us */
1793 extern void ifx_usb_enable_afe_oc(void);
1796 * MEI interrupt handler
1800 * \param regs Pointer to the structure of danube mips registers
1803 static irqreturn_t IFX_MEI_IrqHandle (int int1, void *void0)
1806 DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) void0;
1807 #if defined(CONFIG_LTQ_MEI_FW_LOOPBACK) && defined(DFE_PING_TEST)
1808 dfe_loopback_irq_handler (pDev);
1810 #endif //CONFIG_AMAZON_S_MEI_FW_LOOPBACK
1811 DSL_BSP_CB_Type_t event;
1814 IFX_MEI_EMSG("Error: Got Interrupt but pDev is NULL!!!!\n");
1816 IFX_MEI_DebugRead (pDev, ARC_MEI_MAILBOXR, &scratch, 1);
1817 if (scratch & OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK) {
1818 IFX_MEI_EMSG("Receive Code Swap Request interrupt!!!\n");
1821 else if (scratch & OMB_CLEAREOC_INTERRUPT_CODE) {
1822 // clear eoc message interrupt
1823 IFX_MEI_DMSG("OMB_CLEAREOC_INTERRUPT_CODE\n");
1824 event = DSL_BSP_CB_CEOC_IRQ;
1825 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_STAT, ARC_TO_MEI_MSGAV);
1826 if (dsl_bsp_event_callback[event].function)
1827 (*dsl_bsp_event_callback[event].function)(pDev, event, dsl_bsp_event_callback[event].pData);
1828 } else if (scratch & OMB_REBOOT_INTERRUPT_CODE) {
1830 IFX_MEI_DMSG("OMB_REBOOT_INTERRUPT_CODE\n");
1831 event = DSL_BSP_CB_FIRMWARE_REBOOT;
1833 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_STAT, ARC_TO_MEI_MSGAV);
1835 if (dsl_bsp_event_callback[event].function)
1836 (*dsl_bsp_event_callback[event].function)(pDev, event, dsl_bsp_event_callback[event].pData);
1837 } else { // normal message
1838 IFX_MEI_MailboxRead (pDev, DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, MSG_LENGTH);
1839 if (DSL_DEV_PRIVATE(pDev)-> cmv_waiting == 1) {
1840 DSL_DEV_PRIVATE(pDev)-> arcmsgav = 1;
1841 DSL_DEV_PRIVATE(pDev)-> cmv_waiting = 0;
1842 #if !defined(BSP_PORT_RTEMS)
1843 MEI_WAKEUP_EVENT (DSL_DEV_PRIVATE(pDev)->wait_queue_arcmsgav);
1847 DSL_DEV_PRIVATE(pDev)-> modem_ready_cnt++;
1848 memcpy ((char *) DSL_DEV_PRIVATE(pDev)->Recent_indicator,
1849 (char *) DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, MSG_LENGTH * 2);
1850 if (((DSL_DEV_PRIVATE(pDev)->CMV_RxMsg[0] & 0xff0) >> 4) == D2H_AUTONOMOUS_MODEM_READY_MSG) {
1851 //check ARC ready message
1852 IFX_MEI_DMSG ("Got MODEM_READY_MSG\n");
1853 DSL_DEV_PRIVATE(pDev)->modem_ready = 1;
1854 MEI_WAKEUP_EVENT (DSL_DEV_PRIVATE(pDev)->wait_queue_modemready);
1863 DSL_BSP_ATMLedCBRegister (int (*ifx_adsl_ledcallback) (void))
1865 g_adsl_ledcallback = ifx_adsl_ledcallback;
1870 DSL_BSP_ATMLedCBUnregister (int (*ifx_adsl_ledcallback) (void))
1872 g_adsl_ledcallback = adsl_dummy_ledcallback;
1878 DSL_BSP_EventCBRegister (int (*ifx_adsl_callback)
1879 (DSL_BSP_CB_Event_t * param))
1883 if (DSL_EventCB == NULL) {
1884 DSL_EventCB = ifx_adsl_callback;
1893 DSL_BSP_EventCBUnregister (int (*ifx_adsl_callback)
1894 (DSL_BSP_CB_Event_t * param))
1898 if (DSL_EventCB == ifx_adsl_callback) {
1908 DSL_BSP_GetEventCB (int (**ifx_adsl_callback)
1909 (DSL_BSP_CB_Event_t * param))
1911 *ifx_adsl_callback = DSL_EventCB;
1916 #ifdef CONFIG_LTQ_MEI_FW_LOOPBACK
1917 #define mte_reg_base (0x4800*4+0x20000)
1919 /* Iridia Registers Address Constants */
1920 #define MTE_Reg(r) (int)(mte_reg_base + (r*4))
1922 #define IT_AMODE MTE_Reg(0x0004)
1924 #define TIMER_DELAY (1024)
1925 #define BC0_BYTES (32)
1926 #define BC1_BYTES (30)
1928 #define TIMEOUT_VALUE 2000
1934 for (i = 0; i < cycle; i++);
1938 WriteRegLong (u32 addr, u32 data)
1940 //*((volatile u32 *)(addr)) = data;
1941 IFX_MEI_WRITE_REGISTER_L (data, addr);
1945 ReadRegLong (u32 addr)
1948 //rd_val = *((volatile u32 *)(addr));
1950 return IFX_MEI_READ_REGISTER_L (addr);
1953 /* This routine writes the mailbox with the data in an input array */
1955 WriteMbox (u32 * mboxarray, u32 size)
1957 IFX_MEI_DebugWrite (&dsl_devices[0], IMBOX_BASE, mboxarray, size);
1958 IFX_MEI_DMSG("write to %X\n", IMBOX_BASE);
1959 IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_ME2ARC_INT, MEI_TO_ARC_MSGAV);
1962 /* This routine reads the output mailbox and places the results into an array */
1964 ReadMbox (u32 * mboxarray, u32 size)
1966 IFX_MEI_DebugRead (&dsl_devices[0], OMBOX_BASE, mboxarray, size);
1967 IFX_MEI_DMSG("read from %X\n", OMBOX_BASE);
1971 MEIWriteARCValue (u32 address, u32 value)
1975 /* Write address register */
1976 IFX_MEI_WRITE_REGISTER_L (address, ME_DBG_WR_AD + LTQ_MEI_BASE_ADDR);
1978 /* Write data register */
1979 IFX_MEI_WRITE_REGISTER_L (value, ME_DBG_DATA + LTQ_MEI_BASE_ADDR);
1981 /* wait until complete - timeout at 40 */
1982 for (i = 0; i < 40; i++) {
1983 check = IFX_MEI_READ_REGISTER_L (ME_ARC2ME_STAT + LTQ_MEI_BASE_ADDR);
1985 if ((check & ARC_TO_MEI_DBG_DONE))
1988 /* clear the flag */
1989 IFX_MEI_WRITE_REGISTER_L (ARC_TO_MEI_DBG_DONE, ME_ARC2ME_STAT + LTQ_MEI_BASE_ADDR);
1993 arc_code_page_download (uint32_t arc_code_length, uint32_t * start_address)
1997 IFX_MEI_DMSG("try to download pages,size=%d\n", arc_code_length);
1998 IFX_MEI_ControlModeSet (&dsl_devices[0], MEI_MASTER_MODE);
1999 IFX_MEI_HaltArc (&dsl_devices[0]);
2000 IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_DX_AD, 0);
2001 for (count = 0; count < arc_code_length; count++) {
2002 IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_DX_DATA,
2003 *(start_address + count));
2005 IFX_MEI_ControlModeSet (&dsl_devices[0], JTAG_MASTER_MODE);
2008 load_jump_table (unsigned long addr)
2011 uint32_t addr_le, addr_be;
2012 uint32_t jump_table[32];
2014 for (i = 0; i < 16; i++) {
2015 addr_le = i * 8 + addr;
2016 addr_be = ((addr_le >> 16) & 0xffff);
2017 addr_be |= ((addr_le & 0xffff) << 16);
2018 jump_table[i * 2 + 0] = 0x0f802020;
2019 jump_table[i * 2 + 1] = addr_be;
2020 //printk("jt %X %08X %08X\n",i,jump_table[i*2+0],jump_table[i*2+1]);
2022 arc_code_page_download (32, &jump_table[0]);
2029 dfe_loopback_irq_handler (DSL_DEV_Device_t *pDev)
2031 uint32_t rd_mbox[10];
2033 memset (&rd_mbox[0], 0, 10 * 4);
2034 ReadMbox (&rd_mbox[0], 6);
2035 if (rd_mbox[0] == 0x0) {
2036 FX_MEI_DMSG("Get ARC_ACK\n");
2039 else if (rd_mbox[0] == 0x5) {
2040 IFX_MEI_DMSG("Get ARC_BUSY\n");
2043 else if (rd_mbox[0] == 0x3) {
2044 IFX_MEI_DMSG("Get ARC_EDONE\n");
2045 if (rd_mbox[1] == 0x0) {
2047 IFX_MEI_DMSG("Get E_MEMTEST\n");
2048 if (rd_mbox[2] != 0x1) {
2050 IFX_MEI_DMSG("Get Result %X\n", rd_mbox[2]);
2054 IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_ARC2ME_STAT,
2055 ARC_TO_MEI_DBG_DONE);
2056 MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DFEIR]);
2057 disable_irq (pDev->nIrq[IFX_DFEIR]);
2063 wait_mem_test_result (void)
2068 IFX_MEI_DMSG("Waiting Starting\n");
2069 while (mbox[0] == 0) {
2070 ReadMbox (&mbox[0], 5);
2072 IFX_MEI_DMSG("Try to get mem test result.\n");
2073 ReadMbox (&mbox[0], 5);
2074 if (mbox[0] == 0xA) {
2075 IFX_MEI_DMSG("Success.\n");
2077 else if (mbox[0] == 0xA) {
2078 IFX_MEI_EMSG("Fail,address %X,except data %X,receive data %X\n",
2079 mbox[1], mbox[2], mbox[3]);
2082 IFX_MEI_EMSG("Fail\n");
2087 arc_ping_testing (DSL_DEV_Device_t *pDev)
2089 #define MEI_PING 0x00000001
2090 uint32_t wr_mbox[10], rd_mbox[10];
2093 for (i = 0; i < 10; i++) {
2098 FX_MEI_DMSG("send ping msg\n");
2099 wr_mbox[0] = MEI_PING;
2100 WriteMbox (&wr_mbox[0], 10);
2102 while (got_int == 0) {
2106 IFX_MEI_DMSG("send start event\n");
2112 wr_mbox[3] = (uint32_t) 0xf5acc307e;
2115 wr_mbox[6] = 0x1c000;
2119 WriteMbox (&wr_mbox[0], 10);
2120 DSL_ENABLE_IRQ (pDev->nIrq[IFX_DFEIR]);
2121 //printk("IFX_MEI_MailboxWrite ret=%d\n",i);
2122 IFX_MEI_LongWordWriteOffset (&dsl_devices[0],
2123 (u32) ME_ME2ARC_INT,
2125 IFX_MEI_DMSG("sleeping\n");
2130 IFX_MEI_DMSG("got_int >>>> 3\n");
2132 IFX_MEI_DMSG("got int = %d\n", got_int);
2135 DSL_ENABLE_IRQ (pDev->nIrq[IFX_DFEIR]);
2137 //mbox_read(&rd_mbox[0],6);
2143 static DSL_DEV_MeiError_t
2144 DFE_Loopback_Test (void)
2147 u32 arc_debug_data = 0, temp;
2148 DSL_DEV_Device_t *pDev = &dsl_devices[0];
2149 uint32_t wr_mbox[10];
2151 IFX_MEI_ResetARC (pDev);
2153 arc_debug_data = ACL_CLK_MODE_ENABLE;
2154 IFX_MEI_DebugWrite (pDev, CRI_CCR0, &arc_debug_data, 1);
2156 #if defined( DFE_PING_TEST )|| defined( DFE_ATM_LOOPBACK)
2157 // WriteARCreg(AUX_XMEM_LTEST,0);
2158 IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
2159 #define AUX_XMEM_LTEST 0x128
2160 _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK, AUX_XMEM_LTEST, 0);
2161 IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
2163 // WriteARCreg(AUX_XDMA_GAP,0);
2164 IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
2165 #define AUX_XDMA_GAP 0x114
2166 _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK, AUX_XDMA_GAP, 0);
2167 IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
2169 IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
2171 _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK,
2172 (u32) ME_XDATA_BASE_SH + LTQ_MEI_BASE_ADDR, temp);
2173 IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
2175 i = IFX_MEI_DFEMemoryAlloc (pDev, SDRAM_SEGMENT_SIZE * 16);
2179 for (idx = 0; idx < i; idx++) {
2180 DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].type = FREE_RELOAD;
2181 IFX_MEI_WRITE_REGISTER_L ((((uint32_t) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].address) & 0x0fffffff),
2182 LTQ_MEI_BASE_ADDR + ME_XMEM_BAR_BASE + idx * 4);
2183 IFX_MEI_DMSG("bar%d(%X)=%X\n", idx,
2184 LTQ_MEI_BASE_ADDR + ME_XMEM_BAR_BASE +
2185 idx * 4, (((uint32_t)
2186 ((ifx_mei_device_private_t *)
2187 pDev->pPriv)->adsl_mem_info[idx].
2188 address) & 0x0fffffff));
2189 memset ((u8 *) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].address, 0, SDRAM_SEGMENT_SIZE);
2192 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XDATA_BASE_SH,
2193 ((unsigned long) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[XDATA_REGISTER].address) & 0x0FFFFFFF);
2196 IFX_MEI_EMSG ("cannot load image: no memory\n");
2197 return DSL_DEV_MEI_ERR_FAILURE;
2199 //WriteARCreg(AUX_IC_CTRL,2);
2200 IFX_MEI_DMSG("Setting MEI_MASTER_MODE..\n");
2201 IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
2202 #define AUX_IC_CTRL 0x11
2203 _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK,
2205 IFX_MEI_DMSG("Setting JTAG_MASTER_MODE..\n");
2206 IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
2208 IFX_MEI_DMSG("Halting ARC...\n");
2209 IFX_MEI_HaltArc (&dsl_devices[0]);
2211 #ifdef DFE_PING_TEST
2213 IFX_MEI_DMSG("ping test image size=%d\n", sizeof (arc_ahb_access_code));
2214 memcpy ((u8 *) (DSL_DEV_PRIVATE(pDev)->
2215 adsl_mem_info[0].address + 0x1004),
2216 &arc_ahb_access_code[0], sizeof (arc_ahb_access_code));
2217 load_jump_table (0x80000 + 0x1004);
2219 #endif //DFE_PING_TEST
2221 IFX_MEI_DMSG("ARC ping test code download complete\n");
2222 #endif //defined( DFE_PING_TEST )|| defined( DFE_ATM_LOOPBACK)
2224 IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_ARC2ME_MASK, MSGAV_EN);
2226 arc_code_page_download (1537, &code_array[0]);
2227 IFX_MEI_DMSG("ARC mem test code download complete\n");
2228 #endif //DFE_MEM_TEST
2229 #ifdef DFE_ATM_LOOPBACK
2230 arc_debug_data = 0xf;
2231 arc_code_page_download (sizeof(code_array) / sizeof(*code_array), &code_array[0]);
2232 wr_mbox[0] = 0; //TIMER_DELAY - org: 1024
2233 wr_mbox[1] = 0; //TXFB_START0
2234 wr_mbox[2] = 0x7f; //TXFB_END0 - org: 49
2235 wr_mbox[3] = 0x80; //TXFB_START1 - org: 80
2236 wr_mbox[4] = 0xff; //TXFB_END1 - org: 109
2237 wr_mbox[5] = 0x100; //RXFB_START0 - org: 0
2238 wr_mbox[6] = 0x17f; //RXFB_END0 - org: 49
2239 wr_mbox[7] = 0x180; //RXFB_START1 - org: 256
2240 wr_mbox[8] = 0x1ff; //RXFB_END1 - org: 315
2241 WriteMbox (&wr_mbox[0], 9);
2242 // Start Iridia IT_AMODE (in dmp access) why is it required?
2243 IFX_MEI_DebugWrite (&dsl_devices[0], 0x32010, &arc_debug_data, 1);
2244 #endif //DFE_ATM_LOOPBACK
2245 IFX_MEI_IRQEnable (pDev);
2246 IFX_MEI_DMSG("run ARC...\n");
2247 IFX_MEI_RunArc (&dsl_devices[0]);
2249 #ifdef DFE_PING_TEST
2250 arc_ping_testing (pDev);
2251 #endif //DFE_PING_TEST
2253 wait_mem_test_result ();
2254 #endif //DFE_MEM_TEST
2256 IFX_MEI_DFEMemoryFree (pDev, FREE_ALL);
2257 return DSL_DEV_MEI_ERR_SUCCESS;
2260 #endif //CONFIG_AMAZON_S_MEI_FW_LOOPBACK
2263 IFX_MEI_InitDevNode (int num)
2266 if ((dev_major = register_chrdev (dev_major, IFX_MEI_DEVNAME, &bsp_mei_operations)) < 0) {
2267 IFX_MEI_EMSG ("register_chrdev(%d %s) failed!\n", dev_major, IFX_MEI_DEVNAME);
2275 IFX_MEI_CleanUpDevNode (int num)
2278 unregister_chrdev (dev_major, MEI_DIRNAME);
2283 IFX_MEI_InitDevice (int num)
2285 DSL_DEV_Device_t *pDev;
2287 pDev = &dsl_devices[num];
2290 pDev->pPriv = &sDanube_Mei_Private[num];
2291 memset (pDev->pPriv, 0, sizeof (ifx_mei_device_private_t));
2293 memset (&DSL_DEV_PRIVATE(pDev)->
2294 adsl_mem_info[0], 0,
2295 sizeof (smmu_mem_info_t) * MAX_BAR_REGISTERS);
2298 pDev->nIrq[IFX_DFEIR] = LTQ_MEI_INT;
2299 pDev->nIrq[IFX_DYING_GASP] = LTQ_MEI_DYING_GASP_INT;
2300 pDev->base_address = KSEG1 + LTQ_MEI_BASE_ADDR;
2303 #ifdef CONFIG_LANTIQ_AMAZON_SE
2304 *LTQ_PMU_PWDCR &= ~(1 << 9); // enable dsl
2305 *LTQ_PMU_PWDCR &= ~(1 << 15); // enable AHB base
2307 temp = ltq_r32(LTQ_PMU_PWDCR);
2309 ltq_w32(temp, LTQ_PMU_PWDCR);
2313 DSL_DEV_PRIVATE(pDev)->modem_ready = 0;
2314 DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
2316 MEI_INIT_WAKELIST ("arcq", DSL_DEV_PRIVATE(pDev)->wait_queue_arcmsgav); // for ARCMSGAV
2317 MEI_INIT_WAKELIST ("arcr", DSL_DEV_PRIVATE(pDev)->wait_queue_modemready); // for arc modem ready
2319 MEI_MUTEX_INIT (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema, 1); // semaphore initialization, mutex
2321 MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DFEIR]);
2322 MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DYING_GASP]);
2324 if (request_irq (pDev->nIrq[IFX_DFEIR], IFX_MEI_IrqHandle, 0, "DFEIR", pDev) != 0) {
2325 IFX_MEI_EMSG ("request_irq %d failed!\n", pDev->nIrq[IFX_DFEIR]);
2328 /*if (request_irq (pDev->nIrq[IFX_DYING_GASP], IFX_MEI_Dying_Gasp_IrqHandle, 0, "DYING_GASP", pDev) != 0) {
2329 IFX_MEI_EMSG ("request_irq %d failed!\n", pDev->nIrq[IFX_DYING_GASP]);
2332 // IFX_MEI_DMSG("Device %d initialized. IER %#x\n", num, bsp_get_irq_ier(pDev->nIrq[IFX_DYING_GASP]));
2337 IFX_MEI_ExitDevice (int num)
2339 DSL_DEV_Device_t *pDev;
2340 pDev = &dsl_devices[num];
2345 disable_irq (pDev->nIrq[IFX_DFEIR]);
2346 disable_irq (pDev->nIrq[IFX_DYING_GASP]);
2348 free_irq(pDev->nIrq[IFX_DFEIR], pDev);
2349 free_irq(pDev->nIrq[IFX_DYING_GASP], pDev);
2354 static DSL_DEV_Device_t *
2355 IFX_BSP_HandleGet (int maj, int num)
2357 if (num > BSP_MAX_DEVICES)
2359 return &dsl_devices[num];
2363 DSL_BSP_DriverHandleGet (int maj, int num)
2365 DSL_DEV_Device_t *pDev;
2367 if (num > BSP_MAX_DEVICES)
2370 pDev = &dsl_devices[num];
2371 if (!try_module_get(pDev->owner))
2379 DSL_BSP_DriverHandleDelete (DSL_DEV_Device_t * nHandle)
2381 DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) nHandle;
2384 module_put(pDev->owner);
2389 IFX_MEI_Open (DSL_DRV_inode_t * ino, DSL_DRV_file_t * fil)
2391 int maj = MAJOR (ino->i_rdev);
2392 int num = MINOR (ino->i_rdev);
2394 DSL_DEV_Device_t *pDev = NULL;
2395 if ((pDev = DSL_BSP_DriverHandleGet (maj, num)) == NULL) {
2396 IFX_MEI_EMSG("open(%d:%d) fail!\n", maj, num);
2399 fil->private_data = pDev;
2404 IFX_MEI_Release (DSL_DRV_inode_t * ino, DSL_DRV_file_t * fil)
2406 //int maj = MAJOR(ino->i_rdev);
2407 int num = MINOR (ino->i_rdev);
2408 DSL_DEV_Device_t *pDev;
2410 pDev = &dsl_devices[num];
2413 DSL_BSP_DriverHandleDelete (pDev);
2418 * Callback function for linux userspace program writing
2421 IFX_MEI_Write (DSL_DRV_file_t * filp, const char *buf, size_t size, loff_t * loff)
2423 DSL_DEV_MeiError_t mei_error = DSL_DEV_MEI_ERR_FAILURE;
2425 DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) filp->private_data;
2431 DSL_BSP_FWDownload (pDev, buf, size, (long *) loff, &offset);
2433 if (mei_error == DSL_DEV_MEI_ERR_FAILURE)
2435 return (ssize_t) offset;
2439 * Callback function for linux userspace program ioctling
2442 IFX_MEI_IoctlCopyFrom (int from_kernel, char *dest, char *from, int size)
2447 ret = copy_from_user ((char *) dest, (char *) from, size);
2449 ret = (int)memcpy ((char *) dest, (char *) from, size);
2454 IFX_MEI_IoctlCopyTo (int from_kernel, char *dest, char *from, int size)
2459 ret = copy_to_user ((char *) dest, (char *) from, size);
2461 ret = (int)memcpy ((char *) dest, (char *) from, size);
2466 IFX_MEI_Ioctls (DSL_DEV_Device_t * pDev, int from_kernel, unsigned int command, unsigned long lon)
2469 int meierr = DSL_DEV_MEI_ERR_SUCCESS;
2470 u32 base_address = LTQ_MEI_BASE_ADDR;
2471 DSL_DEV_WinHost_Message_t winhost_msg, m;
2472 DSL_DEV_MeiDebug_t debugrdwr;
2473 DSL_DEV_MeiReg_t regrdwr;
2477 case DSL_FIO_BSP_CMV_WINHOST:
2478 IFX_MEI_IoctlCopyFrom (from_kernel, (char *) winhost_msg.msg.TxMessage,
2479 (char *) lon, MSG_LENGTH * 2);
2481 if ((meierr = DSL_BSP_SendCMV (pDev, winhost_msg.msg.TxMessage, YES_REPLY,
2482 winhost_msg.msg.RxMessage)) != DSL_DEV_MEI_ERR_SUCCESS) {
2483 IFX_MEI_EMSG ("WINHOST CMV fail :TxMessage:%X %X %X %X, RxMessage:%X %X %X %X %X\n",
2484 winhost_msg.msg.TxMessage[0], winhost_msg.msg.TxMessage[1], winhost_msg.msg.TxMessage[2], winhost_msg.msg.TxMessage[3],
2485 winhost_msg.msg.RxMessage[0], winhost_msg.msg.RxMessage[1], winhost_msg.msg.RxMessage[2], winhost_msg.msg.RxMessage[3],
2486 winhost_msg.msg.RxMessage[4]);
2487 meierr = DSL_DEV_MEI_ERR_FAILURE;
2490 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
2491 (char *) winhost_msg.msg.RxMessage,
2496 case DSL_FIO_BSP_CMV_READ:
2497 IFX_MEI_IoctlCopyFrom (from_kernel, (char *) (®rdwr),
2498 (char *) lon, sizeof (DSL_DEV_MeiReg_t));
2500 IFX_MEI_LongWordRead ((u32) regrdwr.iAddress,
2501 (u32 *) & (regrdwr.iData));
2503 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
2504 (char *) (®rdwr),
2505 sizeof (DSL_DEV_MeiReg_t));
2509 case DSL_FIO_BSP_CMV_WRITE:
2510 IFX_MEI_IoctlCopyFrom (from_kernel, (char *) (®rdwr),
2511 (char *) lon, sizeof (DSL_DEV_MeiReg_t));
2513 IFX_MEI_LongWordWrite ((u32) regrdwr.iAddress,
2517 case DSL_FIO_BSP_GET_BASE_ADDRESS:
2518 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
2519 (char *) (&base_address),
2520 sizeof (base_address));
2523 case DSL_FIO_BSP_IS_MODEM_READY:
2524 i = IFX_MEI_IsModemReady (pDev);
2525 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
2526 (char *) (&i), sizeof (int));
2527 meierr = DSL_DEV_MEI_ERR_SUCCESS;
2529 case DSL_FIO_BSP_RESET:
2530 case DSL_FIO_BSP_REBOOT:
2531 meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_RESET);
2532 meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_HALT);
2535 case DSL_FIO_BSP_HALT:
2536 meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_HALT);
2539 case DSL_FIO_BSP_RUN:
2540 meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_RUN);
2542 case DSL_FIO_BSP_BOOTDOWNLOAD:
2543 meierr = IFX_MEI_DownloadBootCode (pDev);
2545 case DSL_FIO_BSP_JTAG_ENABLE:
2546 meierr = IFX_MEI_ArcJtagEnable (pDev, 1);
2549 case DSL_FIO_BSP_REMOTE:
2550 IFX_MEI_IoctlCopyFrom (from_kernel, (char *) (&i),
2551 (char *) lon, sizeof (int));
2553 meierr = IFX_MEI_AdslMailboxIRQEnable (pDev, i);
2556 case DSL_FIO_BSP_DSL_START:
2557 IFX_MEI_DMSG("DSL_FIO_BSP_DSL_START\n");
2558 if ((meierr = IFX_MEI_RunAdslModem (pDev)) != DSL_DEV_MEI_ERR_SUCCESS) {
2559 IFX_MEI_EMSG ("IFX_MEI_RunAdslModem() error...");
2560 meierr = DSL_DEV_MEI_ERR_FAILURE;
2564 case DSL_FIO_BSP_DEBUG_READ:
2565 case DSL_FIO_BSP_DEBUG_WRITE:
2566 IFX_MEI_IoctlCopyFrom (from_kernel,
2567 (char *) (&debugrdwr),
2569 sizeof (debugrdwr));
2571 if (command == DSL_FIO_BSP_DEBUG_READ)
2572 meierr = DSL_BSP_MemoryDebugAccess (pDev,
2573 DSL_BSP_MEMORY_READ,
2581 meierr = DSL_BSP_MemoryDebugAccess (pDev,
2582 DSL_BSP_MEMORY_WRITE,
2590 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon, (char *) (&debugrdwr), sizeof (debugrdwr));
2592 case DSL_FIO_BSP_GET_VERSION:
2593 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon, (char *) (&bsp_mei_version), sizeof (DSL_DEV_Version_t));
2596 #define LTQ_MPS_CHIPID_VERSION_GET(value) (((value) >> 28) & ((1 << 4) - 1))
2597 case DSL_FIO_BSP_GET_CHIP_INFO:
2598 bsp_chip_info.major = 1;
2599 bsp_chip_info.minor = LTQ_MPS_CHIPID_VERSION_GET(*LTQ_MPS_CHIPID);
2600 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon, (char *) (&bsp_chip_info), sizeof (DSL_DEV_HwVersion_t));
2601 meierr = DSL_DEV_MEI_ERR_SUCCESS;
2604 case DSL_FIO_BSP_FREE_RESOURCE:
2605 makeCMV (H2D_CMV_READ, DSL_CMV_GROUP_STAT, 4, 0, 1, NULL, m.msg.TxMessage);
2606 if (DSL_BSP_SendCMV (pDev, m.msg.TxMessage, YES_REPLY, m.msg.RxMessage) != DSL_DEV_MEI_ERR_SUCCESS) {
2607 meierr = DSL_DEV_MEI_ERR_FAILURE;
2610 IFX_MEI_DMSG("RxMessage[4] = %#x\n", m.msg.RxMessage[4]);
2611 if (!(m.msg.RxMessage[4] & DSL_DEV_STAT_CODESWAP_COMPLETE)) {
2612 meierr = DSL_DEV_MEI_ERR_FAILURE;
2615 IFX_MEI_DMSG("Freeing all memories marked FREE_SHOWTIME\n");
2616 IFX_MEI_DFEMemoryFree (pDev, FREE_SHOWTIME);
2617 meierr = DSL_DEV_MEI_ERR_SUCCESS;
2619 #ifdef CONFIG_IFXMIPS_AMAZON_SE
2620 case DSL_FIO_ARC_MUX_TEST:
2621 AMAZON_SE_MEI_ARC_MUX_Test();
2625 // IFX_MEI_EMSG("Invalid IOCTL command: %d\n");
2631 #ifdef CONFIG_IFXMIPS_AMAZON_SE
2632 void AMAZON_SE_MEI_ARC_MUX_Test(void)
2635 *LTQ_RCU_RST |= LTQ_RCU_RST_REQ_MUX_ARC;
2637 p = (u32*)(DFE_LDST_BASE_ADDR + IRAM0_BASE);
2638 IFX_MEI_EMSG("Writing to IRAM0(%p)...\n", p);
2639 for (i = 0; i < IRAM0_SIZE/sizeof(u32); i++, p++) {
2641 if (*p != 0xdeadbeef)
2642 IFX_MEI_EMSG("%p: %#x\n", p, *p);
2645 p = (u32*)(DFE_LDST_BASE_ADDR + IRAM1_BASE);
2646 IFX_MEI_EMSG("Writing to IRAM1(%p)...\n", p);
2647 for (i = 0; i < IRAM1_SIZE/sizeof(u32); i++, p++) {
2649 if (*p != 0xdeadbeef)
2650 IFX_MEI_EMSG("%p: %#x\n", p, *p);
2653 p = (u32*)(DFE_LDST_BASE_ADDR + BRAM_BASE);
2654 IFX_MEI_EMSG("Writing to BRAM(%p)...\n", p);
2655 for (i = 0; i < BRAM_SIZE/sizeof(u32); i++, p++) {
2657 if (*p != 0xdeadbeef)
2658 IFX_MEI_EMSG("%p: %#x\n", p, *p);
2661 p = (u32*)(DFE_LDST_BASE_ADDR + XRAM_BASE);
2662 IFX_MEI_EMSG("Writing to XRAM(%p)...\n", p);
2663 for (i = 0; i < XRAM_SIZE/sizeof(u32); i++, p++) {
2665 if (*p != 0xdeadbeef)
2666 IFX_MEI_EMSG("%p: %#x\n", p, *p);
2669 p = (u32*)(DFE_LDST_BASE_ADDR + YRAM_BASE);
2670 IFX_MEI_EMSG("Writing to YRAM(%p)...\n", p);
2671 for (i = 0; i < YRAM_SIZE/sizeof(u32); i++, p++) {
2673 if (*p != 0xdeadbeef)
2674 IFX_MEI_EMSG("%p: %#x\n", p, *p);
2677 p = (u32*)(DFE_LDST_BASE_ADDR + EXT_MEM_BASE);
2678 IFX_MEI_EMSG("Writing to EXT_MEM(%p)...\n", p);
2679 for (i = 0; i < EXT_MEM_SIZE/sizeof(u32); i++, p++) {
2681 if (*p != 0xdeadbeef)
2682 IFX_MEI_EMSG("%p: %#x\n", p, *p);
2684 *LTQ_RCU_RST &= ~LTQ_RCU_RST_REQ_MUX_ARC;
2688 DSL_BSP_KernelIoctls (DSL_DEV_Device_t * pDev, unsigned int command,
2693 error = IFX_MEI_Ioctls (pDev, 1, command, lon);
2697 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36))
2699 IFX_MEI_UserIoctls (DSL_DRV_inode_t * ino, DSL_DRV_file_t * fil,
2700 unsigned int command, unsigned long lon)
2703 IFX_MEI_UserIoctls (DSL_DRV_file_t * fil,
2704 unsigned int command, unsigned long lon)
2708 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36))
2709 int maj = MAJOR (ino->i_rdev);
2710 int num = MINOR (ino->i_rdev);
2712 DSL_DEV_Device_t *pDev;
2714 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36))
2715 pDev = IFX_BSP_HandleGet (maj, num);
2717 pDev = IFX_BSP_HandleGet (0, 0);
2722 error = IFX_MEI_Ioctls (pDev, 0, command, lon);
2726 #ifdef CONFIG_PROC_FS
2728 * Register a callback function for linux proc filesystem
2731 IFX_MEI_InitProcFS (int num)
2733 struct proc_dir_entry *entry;
2735 DSL_DEV_Device_t *pDev;
2736 reg_entry_t regs_temp[PROC_ITEMS] = {
2737 /* flag, name, description } */
2738 {NULL, "arcmsgav", "arc to mei message ", 0},
2739 {NULL, "cmv_reply", "cmv needs reply", 0},
2740 {NULL, "cmv_waiting", "waiting for cmv reply from arc", 0},
2741 {NULL, "modem_ready_cnt", "ARC to MEI indicator count", 0},
2742 {NULL, "cmv_count", "MEI to ARC CMVs", 0},
2743 {NULL, "reply_count", "ARC to MEI Reply", 0},
2744 {NULL, "Recent_indicator", "most recent indicator", 0},
2745 {NULL, "fw_version", "Firmware Version", 0},
2746 {NULL, "fw_date", "Firmware Date", 0},
2747 {NULL, "meminfo", "Memory Allocation Information", 0},
2748 {NULL, "version", "MEI version information", 0},
2751 pDev = &dsl_devices[num];
2755 regs_temp[0].flag = &(DSL_DEV_PRIVATE(pDev)->arcmsgav);
2756 regs_temp[1].flag = &(DSL_DEV_PRIVATE(pDev)->cmv_reply);
2757 regs_temp[2].flag = &(DSL_DEV_PRIVATE(pDev)->cmv_waiting);
2758 regs_temp[3].flag = &(DSL_DEV_PRIVATE(pDev)->modem_ready_cnt);
2759 regs_temp[4].flag = &(DSL_DEV_PRIVATE(pDev)->cmv_count);
2760 regs_temp[5].flag = &(DSL_DEV_PRIVATE(pDev)->reply_count);
2761 regs_temp[6].flag = (int *) &(DSL_DEV_PRIVATE(pDev)->Recent_indicator);
2763 memcpy ((char *) regs[num], (char *) regs_temp, sizeof (regs_temp));
2765 meidir = proc_mkdir (MEI_DIRNAME, NULL);
2766 if (meidir == NULL) {
2767 IFX_MEI_EMSG ("Failed to create /proc/%s\n", MEI_DIRNAME);
2771 for (i = 0; i < NUM_OF_REG_ENTRY; i++) {
2772 entry = create_proc_entry (regs[num][i].name,
2773 S_IWUSR | S_IRUSR | S_IRGRP |
2776 regs[num][i].low_ino = entry->low_ino;
2777 entry->proc_fops = &IFX_MEI_ProcOperations;
2780 IFX_MEI_EMSG ("Failed to create /proc/%s/%s\n", MEI_DIRNAME, regs[num][i].name);
2788 * Reading function for linux proc filesystem
2791 IFX_MEI_ProcRead (struct file *file, char *buf, size_t nbytes, loff_t * ppos)
2793 int i_ino = (file->f_dentry->d_inode)->i_ino;
2797 reg_entry_t *entry = NULL;
2798 DSL_DEV_Device_t *pDev = NULL;
2799 DSL_DEV_WinHost_Message_t m;
2801 for (num = 0; num < BSP_MAX_DEVICES; num++) {
2802 for (i = 0; i < NUM_OF_REG_ENTRY; i++) {
2803 if (regs[num][i].low_ino == (unsigned short)i_ino) {
2804 entry = ®s[num][i];
2805 pDev = &dsl_devices[num];
2812 else if (strcmp(entry->name, "meminfo") == 0) {
2813 if (*ppos > 0) /* Assume reading completed in previous read */
2815 p += sprintf (p, "No Address Size\n");
2816 for (i = 0; i < MAX_BAR_REGISTERS; i++) {
2817 p += sprintf (p, "BAR[%02d] Addr:0x%08X Size:%lu\n",
2818 i, (u32) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[i].address,
2819 DSL_DEV_PRIVATE(pDev)-> adsl_mem_info[i].size);
2820 //printk( "BAR[%02d] Addr:0x%08X Size:%d\n",i,adsl_mem_info[i].address,adsl_mem_info[i].size);
2823 } else if (strcmp(entry->name, "fw_version") == 0) {
2824 if (*ppos > 0) /* Assume reading completed in previous read */
2826 if (DSL_DEV_PRIVATE(pDev)->modem_ready_cnt < 1)
2830 makeCMV (H2D_CMV_READ, DSL_CMV_GROUP_INFO, 54, 0, 1, NULL, m.msg.TxMessage);
2831 if (DSL_BSP_SendCMV (pDev, m.msg.TxMessage, YES_REPLY, m.msg.RxMessage) != DSL_DEV_MEI_ERR_SUCCESS)
2833 p += sprintf(p, "FW Version: %d.%d.", m.msg.RxMessage[4] & 0xFF, (m.msg.RxMessage[4] >> 8) & 0xFF);
2834 //sub_version:bits 4-7
2835 //int_version:bits 0-3
2836 //spl_appl:bits 8-13
2837 //rel_state:bits 14-15
2838 makeCMV (H2D_CMV_READ, DSL_CMV_GROUP_INFO, 54, 1, 1, NULL, m.msg.TxMessage);
2839 if (DSL_BSP_SendCMV (pDev, m.msg.TxMessage, YES_REPLY, m.msg.RxMessage) != DSL_DEV_MEI_ERR_SUCCESS)
2841 p += sprintf(p, "%d.%d.%d.%d\n",
2842 (m.msg.RxMessage[4] >> 4) & 0xF, m.msg.RxMessage[4] & 0xF,
2843 (m.msg.RxMessage[4] >> 14) & 3, (m.msg.RxMessage[4] >> 8) & 0x3F);
2845 } else if (strcmp(entry->name, "fw_date") == 0) {
2846 if (*ppos > 0) /* Assume reading completed in previous read */
2848 if (DSL_DEV_PRIVATE(pDev)->modem_ready_cnt < 1)
2851 makeCMV (H2D_CMV_READ, DSL_CMV_GROUP_INFO, 55, 0, 1, NULL, m.msg.TxMessage);
2852 if (DSL_BSP_SendCMV (pDev, m.msg.TxMessage, YES_REPLY, m.msg.RxMessage) != DSL_DEV_MEI_ERR_SUCCESS)
2855 p += sprintf(p, "FW Date: %d.%d.", m.msg.RxMessage[4] & 0xFF, (m.msg.RxMessage[4] >> 8) & 0xFF);
2857 makeCMV (H2D_CMV_READ, DSL_CMV_GROUP_INFO, 55, 2, 1, NULL, m.msg.TxMessage);
2858 if (DSL_BSP_SendCMV (pDev, m.msg.TxMessage, YES_REPLY, m.msg.RxMessage) != DSL_DEV_MEI_ERR_SUCCESS)
2861 p += sprintf(p, "%d ", m.msg.RxMessage[4]);
2863 makeCMV (H2D_CMV_READ, DSL_CMV_GROUP_INFO, 55, 1, 1, NULL, m.msg.TxMessage);
2864 if (DSL_BSP_SendCMV (pDev, m.msg.TxMessage, YES_REPLY, m.msg.RxMessage) != DSL_DEV_MEI_ERR_SUCCESS)
2867 p += sprintf(p, "%d:%d\n", (m.msg.RxMessage[4] >> 8) & 0xFF, m.msg.RxMessage[4] & 0xFF);
2870 } else if (strcmp(entry->name, "version") == 0) {
2871 if (*ppos > 0) /* Assume reading completed in previous read */
2873 p += sprintf (p, "IFX MEI V%ld.%ld.%ld\n", bsp_mei_version.major, bsp_mei_version.minor, bsp_mei_version.revision);
2876 } else if (entry->flag != (int *) DSL_DEV_PRIVATE(pDev)->Recent_indicator) {
2877 if (*ppos > 0) /* Assume reading completed in previous read */
2878 return 0; // indicates end of file
2879 p += sprintf (p, "0x%08X\n\n", *(entry->flag));
2881 if ((p - buf) > nbytes) /* Assume output can be read at one time */
2884 if ((int) (*ppos) / ((int) 7) == 16)
2885 return 0; // indicate end of the message
2886 p += sprintf (p, "0x%04X\n\n", *(((u16 *) (entry->flag)) + (int) (*ppos) / ((int) 7)));
2893 * Writing function for linux proc filesystem
2896 IFX_MEI_ProcWrite (struct file *file, const char *buffer, size_t count, loff_t * ppos)
2898 int i_ino = (file->f_dentry->d_inode)->i_ino;
2899 reg_entry_t *current_reg = NULL;
2902 unsigned long newRegValue = 0;
2904 DSL_DEV_Device_t *pDev = NULL;
2906 for (num = 0; num < BSP_MAX_DEVICES; num++) {
2907 for (i = 0; i < NUM_OF_REG_ENTRY; i++) {
2908 if (regs[num][i].low_ino == i_ino) {
2909 current_reg = ®s[num][i];
2910 pDev = &dsl_devices[num];
2915 if ((current_reg == NULL)
2916 || (current_reg->flag ==
2917 (int *) DSL_DEV_PRIVATE(pDev)->
2921 newRegValue = simple_strtoul (buffer, &endp, 0);
2922 *(current_reg->flag) = (int) newRegValue;
2923 return (count + endp - buffer);
2925 #endif //CONFIG_PROC_FS
2927 static int adsl_dummy_ledcallback(void)
2932 int ifx_mei_atm_led_blink(void)
2934 return g_adsl_ledcallback();
2936 EXPORT_SYMBOL(ifx_mei_atm_led_blink);
2938 int ifx_mei_atm_showtime_check(int *is_showtime, struct port_cell_info *port_cell, void **xdata_addr)
2942 if ( is_showtime ) {
2943 *is_showtime = g_tx_link_rate[0] == 0 && g_tx_link_rate[1] == 0 ? 0 : 1;
2947 for ( i = 0; i < port_cell->port_num && i < 2; i++ )
2948 port_cell->tx_link_rate[i] = g_tx_link_rate[i];
2952 if ( g_tx_link_rate[0] == 0 && g_tx_link_rate[1] == 0 )
2955 *xdata_addr = g_xdata_addr;
2960 EXPORT_SYMBOL(ifx_mei_atm_showtime_check);
2963 * Writing function for linux proc filesystem
2966 IFX_MEI_ModuleInit (void)
2969 static struct class *dsl_class;
2971 pr_info("IFX MEI Version %ld.%02ld.%02ld", bsp_mei_version.major, bsp_mei_version.minor, bsp_mei_version.revision);
2973 for (i = 0; i < BSP_MAX_DEVICES; i++) {
2974 if (IFX_MEI_InitDevice (i) != 0) {
2975 IFX_MEI_EMSG("Init device fail!\n");
2978 IFX_MEI_InitDevNode (i);
2979 #ifdef CONFIG_PROC_FS
2980 IFX_MEI_InitProcFS (i);
2983 for (i = 0; i <= DSL_BSP_CB_LAST ; i++)
2984 dsl_bsp_event_callback[i].function = NULL;
2986 #ifdef CONFIG_LTQ_MEI_FW_LOOPBACK
2987 IFX_MEI_DMSG("Start loopback test...\n");
2988 DFE_Loopback_Test ();
2990 dsl_class = class_create(THIS_MODULE, "ifx_mei");
2991 device_create(dsl_class, NULL, MKDEV(MEI_MAJOR, 0), NULL, "ifx_mei");
2996 IFX_MEI_ModuleExit (void)
3001 for (num = 0; num < BSP_MAX_DEVICES; num++) {
3002 IFX_MEI_CleanUpDevNode (num);
3003 #ifdef CONFIG_PROC_FS
3004 for (i = 0; i < NUM_OF_REG_ENTRY; i++) {
3005 remove_proc_entry (regs[num][i].name, meidir);
3010 remove_proc_entry (MEI_DIRNAME, NULL);
3011 for (i = 0; i < BSP_MAX_DEVICES; i++) {
3012 for (i = 0; i < BSP_MAX_DEVICES; i++) {
3013 IFX_MEI_ExitDevice (i);
3018 /* export function for DSL Driver */
3020 /* The functions of MEI_DriverHandleGet and MEI_DriverHandleDelete are
3021 something like open/close in kernel space , where the open could be used
3022 to register a callback for autonomous messages and returns a mei driver context pointer (comparable to the file descriptor in user space)
3023 The context will be required for the multi line chips future! */
3025 EXPORT_SYMBOL (DSL_BSP_DriverHandleGet);
3026 EXPORT_SYMBOL (DSL_BSP_DriverHandleDelete);
3028 EXPORT_SYMBOL (DSL_BSP_ATMLedCBRegister);
3029 EXPORT_SYMBOL (DSL_BSP_ATMLedCBUnregister);
3030 EXPORT_SYMBOL (DSL_BSP_KernelIoctls);
3031 EXPORT_SYMBOL (DSL_BSP_AdslLedInit);
3032 //EXPORT_SYMBOL (DSL_BSP_AdslLedSet);
3033 EXPORT_SYMBOL (DSL_BSP_FWDownload);
3034 EXPORT_SYMBOL (DSL_BSP_Showtime);
3036 EXPORT_SYMBOL (DSL_BSP_MemoryDebugAccess);
3037 EXPORT_SYMBOL (DSL_BSP_SendCMV);
3039 // provide a register/unregister function for DSL driver to register a event callback function
3040 EXPORT_SYMBOL (DSL_BSP_EventCBRegister);
3041 EXPORT_SYMBOL (DSL_BSP_EventCBUnregister);
3043 module_init (IFX_MEI_ModuleInit);
3044 module_exit (IFX_MEI_ModuleExit);
3046 MODULE_LICENSE("Dual BSD/GPL");