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