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