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