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