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