3 Copyright 2002 Broadcom Corp. All Rights Reserved.
5 This program is free software; you can distribute it and/or modify it
6 under the terms of the GNU General Public License (Version 2) as
7 published by the Free Software Foundation.
9 This program is distributed in the hope it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
19 /***************************************************************************
22 * Description: This file contains Linux character device driver entry
23 * for the board related ioctl calls: flash, get free kernel
24 * page and dump kernel memory, etc.
27 ***************************************************************************/
30 #include <linux/version.h>
31 #include <linux/init.h>
33 #include <linux/interrupt.h>
34 #include <linux/capability.h>
35 #include <linux/slab.h>
36 #include <linux/errno.h>
37 #include <linux/module.h>
38 #include <linux/pagemap.h>
39 #include <asm/uaccess.h>
40 #include <linux/wait.h>
41 #include <linux/poll.h>
42 #include <linux/sched.h>
43 #include <linux/list.h>
46 #include <bcm_map_part.h>
49 #include "boardparms.h"
50 #include "flash_api.h"
53 #include "bcm_map_part.h"
57 #if defined (WIRELESS)
58 #define SES_BTN_PRESSED 0x00000001
59 #define SES_EVENTS SES_BTN_PRESSED /*OR all values if any*/
62 #define SES_LED_BLINK 2
70 } MAC_ADDR_INFO, *PMAC_ADDR_INFO;
74 unsigned long ulSdramSize;
75 unsigned long ulPsiSize;
76 unsigned long ulNumMacAddrs;
77 unsigned char ucaBaseMacAddr[NVRAM_MAC_ADDRESS_LEN];
78 MAC_ADDR_INFO MacAddrs[1];
79 } NVRAM_INFO, *PNVRAM_INFO;
83 unsigned long eventmask;
84 } BOARD_IOC, *PBOARD_IOC;
87 /*Dyinggasp callback*/
88 typedef void (*cb_dgasp_t)(void *arg);
89 typedef struct _CB_DGASP__LIST
91 struct list_head list;
93 cb_dgasp_t cb_dgasp_fn;
95 }CB_DGASP_LIST , *PCB_DGASP_LIST;
98 static LED_MAP_PAIR LedMapping[] =
99 { // led name Initial state physical pin (ledMask)
100 {kLedEnd, kLedStateOff, 0, 0, 0, 0, 0, 0},
101 {kLedEnd, kLedStateOff, 0, 0, 0, 0, 0, 0},
102 {kLedEnd, kLedStateOff, 0, 0, 0, 0, 0, 0},
103 {kLedEnd, kLedStateOff, 0, 0, 0, 0, 0, 0},
104 {kLedEnd, kLedStateOff, 0, 0, 0, 0, 0, 0},
105 {kLedEnd, kLedStateOff, 0, 0, 0, 0, 0, 0},
106 {kLedEnd, kLedStateOff, 0, 0, 0, 0, 0, 0},
107 {kLedEnd, kLedStateOff, 0, 0, 0, 0, 0, 0},
108 {kLedEnd, kLedStateOff, 0, 0, 0, 0, 0, 0},
109 {kLedEnd, kLedStateOff, 0, 0, 0, 0, 0, 0} // NOTE: kLedEnd has to be at the end.
113 extern struct file fastcall *fget_light(unsigned int fd, int *fput_needed);
114 extern unsigned int nr_free_pages (void);
115 extern const char *get_system_type(void);
116 extern void kerSysFlashInit(void);
117 extern unsigned long get_nvram_start_addr(void);
118 extern unsigned long get_scratch_pad_start_addr(void);
119 extern unsigned long getMemorySize(void);
120 extern void __init boardLedInit(PLED_MAP_PAIR);
121 extern void boardLedCtrl(BOARD_LED_NAME, BOARD_LED_STATE);
122 extern void kerSysLedRegisterHandler( BOARD_LED_NAME ledName,
123 HANDLE_LED_FUNC ledHwFunc, int ledFailType );
124 extern UINT32 getCrc32(byte *pdata, UINT32 size, UINT32 crc);
127 void __init InitNvramInfo( void );
128 static int board_open( struct inode *inode, struct file *filp );
129 static int board_ioctl( struct inode *inode, struct file *flip, unsigned int command, unsigned long arg );
130 static ssize_t board_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos);
131 static unsigned int board_poll(struct file *filp, struct poll_table_struct *wait);
132 static int board_release(struct inode *inode, struct file *filp);
134 static BOARD_IOC* borad_ioc_alloc(void);
135 static void borad_ioc_free(BOARD_IOC* board_ioc);
137 /* DyingGasp function prototype */
138 static void __init kerSysDyingGaspMapIntr(void);
139 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
140 static irqreturn_t kerSysDyingGaspIsr(int irq, void * dev_id, struct pt_regs * regs);
142 static unsigned int kerSysDyingGaspIsr(void);
144 static void __init kerSysInitDyingGaspHandler( void );
145 static void __exit kerSysDeinitDyingGaspHandler( void );
146 /* -DyingGasp function prototype - */
148 static int ConfigCs(BOARD_IOCTL_PARMS *parms);
149 static void SetPll(int pll_mask, int pll_value);
150 static void SetGpio(int gpio, GPIO_STATE_t state);
152 #if defined (WIRELESS)
153 static irqreturn_t sesBtn_isr(int irq, void *dev_id, struct pt_regs *ptregs);
154 static void __init sesBtn_mapGpio(void);
155 static void __init sesBtn_mapIntr(int context);
156 static unsigned int sesBtn_poll(struct file *file, struct poll_table_struct *wait);
157 static ssize_t sesBtn_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos);
158 static void __init sesLed_mapGpio(void);
159 static void sesLed_ctrl(int action);
160 static void __init ses_board_init(void);
161 static void __exit ses_board_deinit(void);
164 static irqreturn_t reset_isr(int irq, void *dev_id, struct pt_regs *ptregs);
166 static PNVRAM_INFO g_pNvramInfo = NULL;
167 static int g_ledInitialized = 0;
168 static wait_queue_head_t g_board_wait_queue;
169 static CB_DGASP_LIST *g_cb_dgasp_list_head = NULL;
171 static int g_wakeup_monitor = 0;
172 static struct file *g_monitor_file = NULL;
173 static struct task_struct *g_monitor_task = NULL;
174 static unsigned int (*g_orig_fop_poll)
175 (struct file *, struct poll_table_struct *) = NULL;
177 static struct file_operations board_fops =
183 release: board_release,
186 uint32 board_major = 0;
188 #if defined (WIRELESS)
189 static unsigned short sesBtn_irq = BP_NOT_DEFINED;
190 static unsigned short sesBtn_gpio = BP_NOT_DEFINED;
191 static unsigned short sesLed_gpio = BP_NOT_DEFINED;
194 //swda add,05/10/2006
195 #ifdef BACKUP_WLAN_SPROM
196 #define NVRAM_SPROM_TABLE_OFFSET 740
197 #define NVRAM_SPROM_TABLE_SIZE 128
198 static char g_SPROMData[NVRAM_SPROM_TABLE_SIZE];
199 static char g_SROMSaveFlag;
202 #define SN_OFFSET 680
204 static char g_Serial_No[SN_SIZE];
206 #ifdef DEFAULT_WLAN_WEP128
207 #define WEP128KEY_OFFSET 712
208 #define WEP128KEY_SIZE 13
209 static char g_WEP128bit_key[WEP128KEY_SIZE];
212 #ifdef WLAN_ENABLE_CTRL_BUTTON
213 #define GET_WLAN_ENABLE_GPIO_STATUS 0
214 #define GET_BOOT_COMPLETE_FLAG 1
215 #define GPIO_WLAN_ENABLE_STATE 0x40000 //GPIO 18
217 int is_update_flash = 0;
218 int IsMultiConfig = 0;
222 int init_module(void)
224 return( brcm_board_init() );
227 void cleanup_module(void)
230 printk("brcm flash: cleanup_module failed because module is in use\n");
232 brcm_board_cleanup();
236 /* Reset to default */
237 #define K100MS ((100 * HZ) / 1000) // ~100 ms
238 #define DURATION 3*HZ //about 3 seconds
240 struct timer_list gMonitorTimerRST;
241 int gMonitorTimerOnRST = FALSE;
242 void MonitorTimerExpireRST(void);
243 unsigned long PressTime = DURATION;
246 struct timer_list gMonitorTimerPSTN;
247 int gMonitorTimerOnPSTN = FALSE;
248 void MonitorTimerExpirePSTN(void);
249 struct timer_list gMonitorTimerOFFHOOK;
250 int gMonitorTimerOnOFFHOOK = FALSE;
251 void MonitorTimerExpireOFFHOOK(void);
252 int PSTNComingCall=0;
253 int PSTNphone2OFFHOOK=0;
255 int offhook_spin_lock;
256 unsigned long NoActionTimePSTN=0;
257 unsigned long NoActionTimeOFFHOOK=0;
260 #if ODM_AUTO_PROVISION_LAN
261 int autoprovisionlan=0;
264 int boot_complete_flag = 0;
267 void MonitorTimerStartRST(void)
269 #if defined(CONFIG_BCM96358)||defined(CONFIG_BCM96348)||defined(CONFIG_BCM96338)
270 if (gMonitorTimerOnRST)
273 init_timer(&gMonitorTimerRST);
274 gMonitorTimerRST.function = (void*)MonitorTimerExpireRST;
275 gMonitorTimerRST.expires = jiffies + K100MS; // timer expires in ~100ms
276 add_timer(&gMonitorTimerRST);
277 gMonitorTimerOnRST = TRUE;
281 void MonitorTimerExpireRST(void)
283 #if defined(CONFIG_BCM96358)
284 #define GPIO_PRESS_AND_HOLD_RESET GPIO_NUM_TO_MASK_HIGH(36) //GPIO 36
285 //press the GPIO_PRESS_AND_HOLD_RESET button
286 if (!(GPIO->GPIOio_high & (unsigned short)GPIO_PRESS_AND_HOLD_RESET)) {
287 #elif defined(CONFIG_BCM96348)
288 #define GPIO_PRESS_AND_HOLD_RESET 0x80000000 //GPIO 31
289 //press the GPIO_PRESS_AND_HOLD_RESET button
290 if (!(GPIO->GPIOio & (unsigned int)GPIO_PRESS_AND_HOLD_RESET)) {
291 #else //CONFIG_BCM96338
293 //printk("PERF->ExtIrqCfg = %X\n",PERF->ExtIrqCfg);
294 if ( !(PERF->ExtIrqCfg & 0x00000020) ) {
296 #define GPIO_PRESS_AND_HOLD_RESET 0x80 //GPIO 7
297 //press the GPIO_PRESS_AND_HOLD_RESET button
298 if (!(GPIO->GPIOio & (unsigned int)GPIO_PRESS_AND_HOLD_RESET)) {
301 if(!PressTime) PressTime = jiffies;
302 printk("\rHold Reset button for %u seconds", (jiffies - PressTime)/HZ);
303 if(jiffies - PressTime > DURATION) { //reset to factory default setting
304 #if ODM_AUTO_PROVISION_LAN
305 if ( boot_complete_flag == 1 ) {
306 printk("\nReset to factory default setting...\n");
307 kerSysErasePersistent();
308 kerSysMipsSoftReset();
310 printk("\nRun auto provision on lan mode...\n");
311 kerSysLedCtrl( kLedDiag, kLedStateOff );//turn off the Diag LED(red)
312 kerSysLedCtrl( kLedPower, kLedStateFastBlinkContinues );//Power LED blinking(green)
316 printk("\nReset to factory default setting...\n");
317 kerSysErasePersistent();
319 //setDefaultBootline();
320 kerSysMipsSoftReset();
322 gMonitorTimerOnRST = TRUE;
329 gMonitorTimerOnRST = FALSE;
330 MonitorTimerStartRST();
334 void MonitorTimerStartPSTN(void)
336 #if defined(CONFIG_BCM96345)||defined(CONFIG_BCM96348)
337 if (gMonitorTimerOnPSTN)
340 init_timer(&gMonitorTimerPSTN);
341 gMonitorTimerPSTN.function = (void*)MonitorTimerExpirePSTN;
342 gMonitorTimerPSTN.expires = jiffies + K100MS; // timer expires in ~100ms
343 add_timer(&gMonitorTimerPSTN);
344 gMonitorTimerOnPSTN = TRUE;
348 void MonitorTimerExpirePSTN(void)
350 #if defined(CONFIG_BCM96345)
351 #define GPIO_PSTN 0x0200
352 if (GPIO->GPIOio & (unsigned short)GPIO_PSTN){
354 #define GPIO_PSTN 0x800000
355 if (GPIO->GPIOio & (unsigned int)GPIO_PSTN){
357 if(!PSTNComingCall) {
358 spin_lock(&pstn_spin_lock);
359 //printk("**PSTN incoming call\n");
361 spin_unlock(&pstn_spin_lock);
364 //printk(" **PSTN incoming call\n");
367 if(NoActionTimePSTN>50) {
370 spin_lock(&pstn_spin_lock);
371 //printk("**No PSTN incoming call\n");
373 spin_unlock(&pstn_spin_lock);
376 //printk(" *NO PSTN incoming call signal\n");
378 gMonitorTimerOnPSTN = FALSE;
379 MonitorTimerStartPSTN();
382 void MonitorTimerStartOFFHOOK(void)
384 if (gMonitorTimerOnOFFHOOK)
387 init_timer(&gMonitorTimerOFFHOOK);
388 gMonitorTimerOFFHOOK.function = (void*)MonitorTimerExpireOFFHOOK;
389 gMonitorTimerOFFHOOK.expires = jiffies + K100MS; // timer expires in ~100ms
390 add_timer(&gMonitorTimerOFFHOOK);
391 gMonitorTimerOnOFFHOOK = TRUE;
394 void MonitorTimerExpireOFFHOOK(void)
396 #if defined(CONFIG_BCM96345)
397 #define GPIO_OFFHOOK 0x0002
398 if (!(GPIO->GPIOio & (unsigned short)GPIO_OFFHOOK)){
400 #define GPIO_OFFHOOK 0x400000
401 if (!(GPIO->GPIOio & (unsigned int)GPIO_OFFHOOK)){
403 if((!PSTNphone2OFFHOOK)&&(!PSTNComingCall)) {
404 spin_lock(&offhook_spin_lock);
405 // printk("**PSTN OFFHOOK\n");
407 spin_unlock(&offhook_spin_lock);
409 NoActionTimeOFFHOOK=0;
410 //printk("**PSTN OFFHOOK\n");
412 NoActionTimeOFFHOOK++;
413 if(NoActionTimeOFFHOOK>20) {
414 NoActionTimeOFFHOOK=0;
415 if(PSTNphone2OFFHOOK) {
416 spin_lock(&offhook_spin_lock);
417 //printk("**No PSTN OFFHOOK\n");
419 spin_unlock(&offhook_spin_lock);
422 //printk(" **PSTN ONHOOK\n");
424 gMonitorTimerOnOFFHOOK = FALSE;
425 MonitorTimerStartOFFHOOK();
429 //swda add,11/02/2005
431 struct timer_list gLLLTestLedTimer;
432 static int gLLLTestLedTimerRunning = 0;
434 void LLLTestLedTimerExpireFunc(void)
436 kerSysLedCtrl( kLedPPP, kLedStateOff );
437 gLLLTestLedTimerRunning = 0;
439 void LLLTestLedTimerStart(void)
441 init_timer(&gLLLTestLedTimer);
442 gLLLTestLedTimer.function = (void*)LLLTestLedTimerExpireFunc;
443 gLLLTestLedTimer.expires = jiffies + 30*HZ; // timer expires in ~30s
444 add_timer(&gLLLTestLedTimer);
445 gLLLTestLedTimerRunning = 1;
447 void LLLTestLedTimerDelete(void)
449 if (gLLLTestLedTimerRunning ) {
450 del_timer(&gLLLTestLedTimer);
451 gLLLTestLedTimerRunning = 0;
457 static int __init brcm_board_init( void )
459 typedef int (*BP_LED_FUNC) (unsigned short *);
460 static struct BpLedInformation
462 BOARD_LED_NAME ledName;
464 BP_LED_FUNC bpFuncFail;
466 {{kLedAdsl, BpGetAdslLedGpio, BpGetAdslFailLedGpio},
467 {kLedWireless, BpGetWirelessLedGpio, NULL},
468 {kLedUsb, BpGetUsbLedGpio, NULL},
469 {kLedHpna, BpGetHpnaLedGpio, NULL},
470 {kLedWanData, BpGetWanDataLedGpio, NULL},
471 {kLedPPP, BpGetPppLedGpio, BpGetPppFailLedGpio},
472 {kLedVoip, BpGetVoipLedGpio, NULL},
473 {kLedSes, BpGetWirelessSesLedGpio, NULL},
474 {kLedDiag, BpGetBootloaderStopLedGpio, NULL},
475 {kLedPower, BpGetBootloaderPowerOnLedGpio, NULL},
476 {kLedEnd, NULL, NULL}
479 unsigned short pah_irq;
482 ret = register_chrdev(BOARD_DRV_MAJOR, "bcrmboard", &board_fops );
484 printk( "brcm_board_init(major %d): fail to register device.\n",BOARD_DRV_MAJOR);
487 PLED_MAP_PAIR pLedMap = LedMapping;
489 struct BpLedInformation *pInfo;
490 ETHERNET_MAC_INFO EnetInfo;
492 printk("brcmboard: brcm_board_init entry\n");
493 board_major = BOARD_DRV_MAJOR;
496 for( pInfo = bpLedInfo; pInfo->ledName != kLedEnd; pInfo++ )
498 if( pInfo->bpFunc && (*pInfo->bpFunc) (&gpio) == BP_SUCCESS &&
499 gpio != BP_HW_DEFINED_AH && gpio != BP_HW_DEFINED_AL )
501 pLedMap->ledName = pInfo->ledName;
502 pLedMap->ledMask = GPIO_NUM_TO_MASK(gpio);
503 pLedMap->ledActiveLow = (gpio & BP_ACTIVE_LOW) ? 1 : 0;
504 pLedMap->ledSerial = (gpio & BP_GPIO_SERIAL) ? 1 : 0;
505 //swda add,05/17/2006
506 if (pInfo->ledName == kLedPower)
507 pLedMap->ledInitState = kLedStateOff;
508 if (pInfo->ledName == kLedDiag)
509 pLedMap->ledInitState = kLedStateOn;
512 if( pInfo->bpFuncFail && (*pInfo->bpFuncFail)(&gpio)==BP_SUCCESS &&
513 gpio != BP_HW_DEFINED_AH && gpio != BP_HW_DEFINED_AL )
515 pLedMap->ledName = pInfo->ledName;
516 pLedMap->ledMaskFail = GPIO_NUM_TO_MASK(gpio);
517 pLedMap->ledActiveLowFail = (gpio & BP_ACTIVE_LOW) ? 1 : 0;
518 pLedMap->ledSerialFail = (gpio & BP_GPIO_SERIAL) ? 1 : 0;
520 if( pLedMap->ledName != kLedEnd )
524 if( BpGetEthernetMacInfo( &EnetInfo, 1 ) == BP_SUCCESS )
526 if( EnetInfo.usGpioPhyLinkSpeed != BP_NOT_DEFINED )
528 /* The internal Ethernet PHY has a GPIO for 10/100 link speed. */
529 gpio = EnetInfo.usGpioPhyLinkSpeed;
530 pLedMap->ledName = kLedEphyLinkSpeed;
531 pLedMap->ledMask = GPIO_NUM_TO_MASK(gpio);
532 pLedMap->ledActiveLow = (gpio & BP_ACTIVE_LOW) ? 1 : 0;
533 pLedMap->ledSerial = (gpio & BP_GPIO_SERIAL) ? 1 : 0;
538 init_waitqueue_head(&g_board_wait_queue);
539 #if defined (WIRELESS)
542 kerSysInitDyingGaspHandler();
543 kerSysDyingGaspMapIntr();
545 boardLedInit(LedMapping);
546 g_ledInitialized = 1;
548 if( BpGetPressAndHoldResetExtIntr(&pah_irq) == BP_SUCCESS )
550 pah_irq += INTERRUPT_ID_EXTERNAL_0;
551 BcmHalMapInterrupt((FN_HANDLER)reset_isr, 0, pah_irq);
552 BcmHalInterruptEnable(pah_irq);
555 //Start the timer to detect the GPIO_PRESS_AND_HOLD_RESET
556 #ifdef CONFIG_BCM96338 //swda add
557 GPIO->GPIODir &= 0xFFFFFF7F;//GPIO 7 used as reset to default pin, set GPIO 7 as input
559 GPIO->GPIODir |= 0x0004; //set GPIO2 as output pin,so that we can control GPIO4 value
560 GPIO->GPIOio |= 0x0004; //pull GPIO2 high, so that we can control ppp led
563 #ifdef CONFIG_BCM96348
564 GPIO->GPIODir |= 0x0010; //set GPIO4 as output pin,so that we can control GPIO4 value
565 GPIO->GPIOio |= 0x0010; //pull GPIO4 high, so that we can control ppp led via GPIO3
568 #ifdef CONFIG_BCM96358
569 GPIO->GPIODir_high &= (~GPIO_NUM_TO_MASK_HIGH(36));//GPIO 36 used as reset to default pin, set GPIO 36 as input
572 #ifdef WLAN_ENABLE_CTRL_BUTTON
573 GPIO->GPIODir &= (unsigned int)(~GPIO_WLAN_ENABLE_STATE);//GPIO 18 used to inform wlan to turn off, so set GPIO 18 as input pin
576 MonitorTimerStartRST();
578 MonitorTimerStartPSTN();
579 MonitorTimerStartOFFHOOK();
585 void __init InitNvramInfo( void )
587 PNVRAM_DATA pNvramData = (PNVRAM_DATA) get_nvram_start_addr();
589 unsigned long ulNumMacAddrs = pNvramData->ulNumMacAddrs;
591 unsigned long ulNumMacAddrs = 12; /* We skip what the user set up. change it max 12, each PVC use one but we change first byte */
593 if( ulNumMacAddrs > 0 && ulNumMacAddrs <= NVRAM_MAC_COUNT_MAX )
595 unsigned long ulNvramInfoSize =
596 sizeof(NVRAM_INFO) + ((sizeof(MAC_ADDR_INFO) - 1) * ulNumMacAddrs);
598 g_pNvramInfo = (PNVRAM_INFO) kmalloc( ulNvramInfoSize, GFP_KERNEL );
602 unsigned long ulPsiSize;
603 if( BpGetPsiSize( &ulPsiSize ) != BP_SUCCESS )
604 ulPsiSize = NVRAM_PSI_DEFAULT;
605 memset( g_pNvramInfo, 0x00, ulNvramInfoSize );
606 g_pNvramInfo->ulPsiSize = ulPsiSize * 1024;
608 g_pNvramInfo->ulNumMacAddrs = pNvramData->ulNumMacAddrs;
610 g_pNvramInfo->ulNumMacAddrs = 12;
612 memcpy( g_pNvramInfo->ucaBaseMacAddr, pNvramData->ucaBaseMacAddr,
613 NVRAM_MAC_ADDRESS_LEN );
614 g_pNvramInfo->ulSdramSize = getMemorySize();
617 printk("ERROR - Could not allocate memory for NVRAM data\n");
620 printk("ERROR - Invalid number of MAC addresses (%ld) is configured.\n",
623 //swda add,04/08/2005
624 #ifdef BACKUP_WLAN_SPROM
625 g_SROMSaveFlag = pNvramData->sprom_saved_flag;
626 kerSysNvRamGet(g_SPROMData, NVRAM_SPROM_TABLE_SIZE, NVRAM_SPROM_TABLE_OFFSET);
629 kerSysNvRamGet(g_Serial_No, SN_SIZE, SN_OFFSET);
631 #ifdef DEFAULT_WLAN_WEP128
632 kerSysNvRamGet(g_WEP128bit_key,WEP128KEY_SIZE,WEP128KEY_OFFSET);
633 { //check if valid ASCII string
634 int key_index,valid_key;
637 for (key_index=0;key_index<WEP128KEY_SIZE;key_index++) {
638 //printable ASCII character 0x21~0x7E
639 if ( g_WEP128bit_key[key_index]<0x21 || g_WEP128bit_key[key_index]>0x7e ) {
645 strcpy(g_WEP128bit_key,"0000000000000");
651 void __exit brcm_board_cleanup( void )
653 printk("brcm_board_cleanup()\n");
655 if (board_major != -1)
657 #if defined (WIRELESS)
660 kerSysDeinitDyingGaspHandler();
661 unregister_chrdev(board_major, "board_ioctl");
665 static BOARD_IOC* borad_ioc_alloc(void)
667 BOARD_IOC *board_ioc =NULL;
668 board_ioc = (BOARD_IOC*) kmalloc( sizeof(BOARD_IOC) , GFP_KERNEL );
671 memset(board_ioc, 0, sizeof(BOARD_IOC));
676 static void borad_ioc_free(BOARD_IOC* board_ioc)
685 static int board_open( struct inode *inode, struct file *filp )
687 filp->private_data = borad_ioc_alloc();
689 if (filp->private_data == NULL)
695 static int board_release(struct inode *inode, struct file *filp)
697 BOARD_IOC *board_ioc = filp->private_data;
699 wait_event_interruptible(g_board_wait_queue, 1);
700 borad_ioc_free(board_ioc);
706 static unsigned int board_poll(struct file *filp, struct poll_table_struct *wait)
708 unsigned int mask = 0;
709 #if defined (WIRELESS)
710 BOARD_IOC *board_ioc = filp->private_data;
713 poll_wait(filp, &g_board_wait_queue, wait);
714 #if defined (WIRELESS)
715 if(board_ioc->eventmask & SES_EVENTS){
716 mask |= sesBtn_poll(filp, wait);
724 static ssize_t board_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos)
726 #if defined (WIRELESS)
727 BOARD_IOC *board_ioc = filp->private_data;
728 if(board_ioc->eventmask & SES_EVENTS){
729 return sesBtn_read(filp, buffer, count, ppos);
735 //**************************************************************************************
736 // Utitlities for dump memory, free kernel pages, mips soft reset, etc.
737 //**************************************************************************************
739 /***********************************************************************
740 * Function Name: dumpaddr
741 * Description : Display a hex dump of the specified address.
742 ***********************************************************************/
743 void dumpaddr( unsigned char *pAddr, int nLen )
745 static char szHexChars[] = "0123456789abcdef";
748 unsigned char ch, *q;
754 sprintf( szLine, "%8.8lx: ", (unsigned long) pAddr );
755 p = szLine + strlen(szLine);
757 for(i = 0; i < 16 && nLen > 0; i += sizeof(long), nLen -= sizeof(long))
759 ul = *(unsigned long *) &pAddr[i];
760 q = (unsigned char *) &ul;
761 for( j = 0; j < sizeof(long); j++ )
763 *p++ = szHexChars[q[j] >> 4];
764 *p++ = szHexChars[q[j] & 0x0f];
769 for( j = 0; j < 16 - i; j++ )
770 *p++ = ' ', *p++ = ' ', *p++ = ' ';
772 *p++ = ' ', *p++ = ' ', *p++ = ' ';
774 for( j = 0; j < i; j++ )
777 *p++ = (ch > ' ' && ch < '~') ? ch : '.';
781 printk( "%s\r\n", szLine );
789 void kerSysMipsSoftReset(void)
791 #if defined(CONFIG_BCM96348)
792 if (PERF->RevID == 0x634800A1) {
793 typedef void (*FNPTR) (void);
794 FNPTR bootaddr = (FNPTR) FLASH_BASE;
797 /* Disable interrupts. */
800 /* Reset all blocks. */
801 PERF->BlockSoftReset &= ~BSR_ALL_BLOCKS;
802 for( i = 0; i < 1000000; i++ )
804 PERF->BlockSoftReset |= BSR_ALL_BLOCKS;
805 /* Jump to the power on address. */
809 PERF->pll_control |= SOFT_RESET; // soft reset mips
811 PERF->pll_control |= SOFT_RESET; // soft reset mips
816 int kerSysGetMacAddress( unsigned char *pucaMacAddr, unsigned long ulId )
818 const unsigned long constMacAddrIncIndex = 3;
820 PMAC_ADDR_INFO pMai = NULL;
821 PMAC_ADDR_INFO pMaiFreeNoId = NULL;
822 PMAC_ADDR_INFO pMaiFreeId = NULL;
823 unsigned long i = 0, ulIdxNoId = 0, ulIdxId = 0, baseMacAddr = 0;
824 unsigned long ulWanBaseIdxId = 1;//swda add,05/08/2006
826 //swda add,05/08/2006
827 #ifdef BRCM_DRIVER_USB
828 ulWanBaseIdxId += 2;//ulWanBaseIdxId = 3
831 #ifndef BACKUP_WLAN_SPROM //only wlan on board need mac assignment
832 ulWanBaseIdxId += 1;//ulWanBaseIdxId = 2 or 4
837 /* baseMacAddr = last 3 bytes of the base MAC address treated as a 24 bit integer */
838 memcpy((unsigned char *) &baseMacAddr,
839 &g_pNvramInfo->ucaBaseMacAddr[constMacAddrIncIndex],
840 NVRAM_MAC_ADDRESS_LEN - constMacAddrIncIndex);
843 for( i = 0, pMai = g_pNvramInfo->MacAddrs; i < g_pNvramInfo->ulNumMacAddrs;
846 if( ulId == pMai->ulId || ulId == MAC_ADDRESS_ANY )
848 /* This MAC address has been used by the caller in the past. */
849 baseMacAddr = (baseMacAddr + i) << 8;
850 memcpy( pucaMacAddr, g_pNvramInfo->ucaBaseMacAddr,
851 constMacAddrIncIndex);
852 memcpy( pucaMacAddr + constMacAddrIncIndex, (unsigned char *)
853 &baseMacAddr, NVRAM_MAC_ADDRESS_LEN - constMacAddrIncIndex );
855 pMaiFreeNoId = pMaiFreeId = NULL;
859 if( pMai->chInUse == 0 )
861 if( pMai->ulId == 0 && pMaiFreeNoId == NULL )
863 /* This is an available MAC address that has never been
870 if( pMai->ulId != 0 && pMaiFreeId == NULL )
872 /* This is an available MAC address that has been used
873 * before. Use addresses that have never been used
874 * first, before using this one.
882 if( pMaiFreeNoId || pMaiFreeId )
884 /* An available MAC address was found. */
885 memcpy(pucaMacAddr, g_pNvramInfo->ucaBaseMacAddr,NVRAM_MAC_ADDRESS_LEN);
888 //swda modify,05/08/2006
889 if ( ulIdxNoId >= ulWanBaseIdxId ) {
890 pucaMacAddr[0] += (ulIdxNoId-ulWanBaseIdxId)*8+2;
892 baseMacAddr = (baseMacAddr + ulIdxNoId) << 8;
893 memcpy( pucaMacAddr, g_pNvramInfo->ucaBaseMacAddr,
894 constMacAddrIncIndex);
895 memcpy( pucaMacAddr + constMacAddrIncIndex, (unsigned char *)
896 &baseMacAddr, NVRAM_MAC_ADDRESS_LEN - constMacAddrIncIndex );
899 pMaiFreeNoId->ulId = ulId;
900 pMaiFreeNoId->chInUse = 1;
904 //swda modify,05/08/2006
905 if ( ulIdxId >= ulWanBaseIdxId ) {
906 pucaMacAddr[0] += (ulIdxId-ulWanBaseIdxId)*8+2;
908 baseMacAddr = (baseMacAddr + ulIdxId) << 8;
909 memcpy( pucaMacAddr, g_pNvramInfo->ucaBaseMacAddr,
910 constMacAddrIncIndex);
911 memcpy( pucaMacAddr + constMacAddrIncIndex, (unsigned char *)
912 &baseMacAddr, NVRAM_MAC_ADDRESS_LEN - constMacAddrIncIndex );
915 pMaiFreeId->ulId = ulId;
916 pMaiFreeId->chInUse = 1;
920 if( i == g_pNvramInfo->ulNumMacAddrs )
921 nRet = -EADDRNOTAVAIL;
924 } /* kerSysGetMacAddr */
926 int kerSysReleaseMacAddress( unsigned char *pucaMacAddr )
928 const unsigned long constMacAddrIncIndex = 3;
930 unsigned long ulIdx = 0;
931 unsigned long baseMacAddr = 0;
932 unsigned long relMacAddr = 0;
934 /* baseMacAddr = last 3 bytes of the base MAC address treated as a 24 bit integer */
935 memcpy((unsigned char *) &baseMacAddr,
936 &g_pNvramInfo->ucaBaseMacAddr[constMacAddrIncIndex],
937 NVRAM_MAC_ADDRESS_LEN - constMacAddrIncIndex);
940 /* Get last 3 bytes of MAC address to release. */
941 memcpy((unsigned char *) &relMacAddr, &pucaMacAddr[constMacAddrIncIndex],
942 NVRAM_MAC_ADDRESS_LEN - constMacAddrIncIndex);
945 ulIdx = relMacAddr - baseMacAddr;
947 if( ulIdx < g_pNvramInfo->ulNumMacAddrs )
949 PMAC_ADDR_INFO pMai = &g_pNvramInfo->MacAddrs[ulIdx];
950 if( pMai->chInUse == 1 )
958 } /* kerSysReleaseMacAddr */
960 int kerSysGetSdramSize( void )
962 return( (int) g_pNvramInfo->ulSdramSize );
963 } /* kerSysGetSdramSize */
966 void kerSysLedCtrl(BOARD_LED_NAME ledName, BOARD_LED_STATE ledState)
968 if (g_ledInitialized)
969 boardLedCtrl(ledName, ledState);
972 unsigned int kerSysMonitorPollHook( struct file *f, struct poll_table_struct *t)
974 int mask = (*g_orig_fop_poll) (f, t);
976 if( g_wakeup_monitor == 1 && g_monitor_file == f )
978 /* If g_wakeup_monitor is non-0, the user mode application needs to
979 * return from a blocking select function. Return POLLPRI which will
980 * cause the select to return with the exception descriptor set.
983 g_wakeup_monitor = 0;
989 /* Put the user mode application that monitors link state on a run queue. */
990 void kerSysWakeupMonitorTask( void )
992 g_wakeup_monitor = 1;
994 wake_up_process( g_monitor_task );
996 //#if defined(CONFIG_BCM96358)
998 static PFILE_TAG getTagFromPartition(int imageNumber)
1000 static unsigned char sectAddr1[sizeof(FILE_TAG)];
1001 static unsigned char sectAddr2[sizeof(FILE_TAG)];
1004 PFILE_TAG pTag = NULL;
1005 unsigned char *pBase = flash_get_memptr(0);
1006 unsigned char *pSectAddr = NULL;
1008 /* The image tag for the first image is always after the boot loader.
1009 * The image tag for the second image, if it exists, is at one half
1010 * of the flash size.
1012 if( imageNumber == 1 )
1014 blk = flash_get_blk((int) (pBase + FLASH_LENGTH_BOOT_ROM));
1015 pSectAddr = sectAddr1;
1018 if( imageNumber == 2 )
1020 blk = flash_get_blk((int) (pBase + (flash_get_total_size() / 2)));
1021 pSectAddr = sectAddr2;
1026 memset(pSectAddr, 0x00, sizeof(FILE_TAG));
1027 flash_read_buf((unsigned short) blk, 0, pSectAddr, sizeof(FILE_TAG));
1028 crc = CRC32_INIT_VALUE;
1029 crc = getCrc32(pSectAddr, (UINT32)TAG_LEN-TOKEN_LEN, crc);
1030 pTag = (PFILE_TAG) pSectAddr;
1031 if (crc != (UINT32)(*(UINT32*)(pTag->tagValidationToken)))
1038 static int getPartitionFromTag( PFILE_TAG pTag )
1044 PFILE_TAG pTag1 = getTagFromPartition(1);
1045 PFILE_TAG pTag2 = getTagFromPartition(2);
1046 int sequence = simple_strtoul(pTag->imageSequence, NULL, 10);
1047 int sequence1 = (pTag1) ? simple_strtoul(pTag1->imageSequence, NULL, 10)
1049 int sequence2 = (pTag2) ? simple_strtoul(pTag2->imageSequence, NULL, 10)
1052 if( pTag1 && sequence == sequence1 )
1055 if( pTag2 && sequence == sequence2 )
1062 static PFILE_TAG getBootImageTag(void)
1064 PFILE_TAG pTag = NULL;
1065 PFILE_TAG pTag1 = getTagFromPartition(1);
1066 PFILE_TAG pTag2 = getTagFromPartition(2);
1068 if( pTag1 && pTag2 )
1070 /* Two images are flashed. */
1071 int sequence1 = simple_strtoul(pTag1->imageSequence, NULL, 10);
1072 int sequence2 = simple_strtoul(pTag2->imageSequence, NULL, 10);
1074 char bootPartition = BOOT_LATEST_IMAGE;
1075 NVRAM_DATA nvramData;
1077 memcpy((char *) &nvramData, (char *) get_nvram_start_addr(),
1079 for( p = nvramData.szBootline; p[2] != '\0'; p++ )
1080 if( p[0] == 'p' && p[1] == '=' )
1082 bootPartition = p[2];
1086 if( bootPartition == BOOT_LATEST_IMAGE )
1087 pTag = (sequence2 > sequence1) ? pTag2 : pTag1;
1088 else /* Boot from the image configured. */
1089 pTag = (sequence2 < sequence1) ? pTag2 : pTag1;
1092 /* One image is flashed. */
1093 pTag = (pTag2) ? pTag2 : pTag1;
1098 static void UpdateImageSequenceNumber( unsigned char *imageSequence )
1100 int newImageSequence = 0;
1101 PFILE_TAG pTag = getTagFromPartition(1);
1104 newImageSequence = simple_strtoul(pTag->imageSequence, NULL, 10);
1106 pTag = getTagFromPartition(2);
1107 if(pTag && simple_strtoul(pTag->imageSequence, NULL, 10) > newImageSequence)
1108 newImageSequence = simple_strtoul(pTag->imageSequence, NULL, 10);
1111 sprintf(imageSequence, "%d", newImageSequence);
1114 static int flashFsKernelImage( int destAddr, unsigned char *imagePtr,
1118 PFILE_TAG pTag = (PFILE_TAG) imagePtr;
1119 int rootfsAddr = simple_strtoul(pTag->rootfsAddress, NULL, 10) + BOOT_OFFSET;
1120 int kernelAddr = simple_strtoul(pTag->kernelAddress, NULL, 10) + BOOT_OFFSET;
1122 char *tagFs = imagePtr;
1123 unsigned int baseAddr = (unsigned int) flash_get_memptr(0);
1124 unsigned int totalSize = (unsigned int) flash_get_total_size();
1125 unsigned int availableSizeOneImg = totalSize -
1126 ((unsigned int) rootfsAddr - baseAddr) - FLASH_RESERVED_AT_END;
1127 unsigned int reserveForTwoImages =
1128 (FLASH_LENGTH_BOOT_ROM > FLASH_RESERVED_AT_END)
1129 ? FLASH_LENGTH_BOOT_ROM : FLASH_RESERVED_AT_END;
1130 unsigned int availableSizeTwoImgs =
1131 (totalSize / 2) - reserveForTwoImages;
1132 unsigned int newImgSize = simple_strtoul(pTag->rootfsLen, NULL, 10) +
1133 simple_strtoul(pTag->kernelLen, NULL, 10);
1134 PFILE_TAG pCurTag = getBootImageTag();
1135 UINT32 crc = CRC32_INIT_VALUE;
1136 unsigned int curImgSize = 0;
1137 NVRAM_DATA nvramData;
1139 memcpy((char *)&nvramData, (char *)get_nvram_start_addr(),sizeof(nvramData));
1143 curImgSize = simple_strtoul(pCurTag->rootfsLen, NULL, 10) +
1144 simple_strtoul(pCurTag->kernelLen, NULL, 10);
1147 if( newImgSize > availableSizeOneImg)
1149 printk("Illegal image size %d. Image size must not be greater "
1150 "than %d.\n", newImgSize, availableSizeOneImg);
1154 // If the current image fits in half the flash space and the new
1155 // image to flash also fits in half the flash space, then flash it
1156 // in the partition that is not currently being used to boot from.
1157 if( curImgSize <= availableSizeTwoImgs &&
1158 newImgSize <= availableSizeTwoImgs &&
1159 getPartitionFromTag( pCurTag ) == 1 )
1161 // Update rootfsAddr to point to the second boot partition.
1162 int offset = (totalSize / 2) + TAG_LEN;
1164 sprintf(((PFILE_TAG) tagFs)->kernelAddress, "%lu",
1165 (unsigned long) IMAGE_BASE + offset + (kernelAddr - rootfsAddr));
1166 kernelAddr = baseAddr + offset + (kernelAddr - rootfsAddr);
1168 sprintf(((PFILE_TAG) tagFs)->rootfsAddress, "%lu",
1169 (unsigned long) IMAGE_BASE + offset);
1170 rootfsAddr = baseAddr + offset;
1173 UpdateImageSequenceNumber( ((PFILE_TAG) tagFs)->imageSequence );
1174 /* we do not modify Tag so crc does not need to modify */
1175 crc = getCrc32((unsigned char *)tagFs, (UINT32)TAG_LEN-TOKEN_LEN, crc);
1176 *(unsigned long *) &((PFILE_TAG) tagFs)->tagValidationToken[0] = crc;
1179 if( (status = kerSysBcmImageSet((rootfsAddr-TAG_LEN), tagFs,
1180 TAG_LEN + newImgSize)) != 0 )
1182 printk("Failed to flash root file system. Error: %d\n", status);
1186 for( p = nvramData.szBootline; p[2] != '\0'; p++ )
1187 if( p[0] == 'p' && p[1] == '=' && p[2] != BOOT_LATEST_IMAGE )
1189 UINT32 crc = CRC32_INIT_VALUE;
1191 // Change boot partition to boot from new image.
1192 p[2] = BOOT_LATEST_IMAGE;
1194 nvramData.ulCheckSum = 0;
1195 crc = getCrc32((char *)&nvramData, (UINT32) sizeof(NVRAM_DATA), crc);
1196 nvramData.ulCheckSum = crc;
1197 kerSysNvRamSet( (char *) &nvramData, sizeof(nvramData), 0);
1204 static PFILE_TAG getBootImageTag(void)
1207 int totalBlks = flash_get_numsectors();
1208 int totalSize = flash_get_total_size();
1209 int startblock,redo;
1211 unsigned char *sectAddr;
1212 unsigned char bootf1,bootf2,nbootflag=0;
1215 int totalImageSize = 0;/* vic add to check image crc */
1218 if (totalSize == 0x800000) {
1219 bootf1 = *(unsigned char*) (FLASH_BASE+(totalSize/2)-1); /*see design note 4MB flash layout*/
1220 bootf2 = *(unsigned char*) (FLASH_BASE+totalSize-FLASH_RESERVED_AT_END -1);
1221 printk("bootf %02x/%02x ",bootf1,bootf2);
1222 if ((bootf1 >> 2) == 0 && bootf1 )
1224 if ((bootf2 >> 2) == 0 && bootf2 )
1225 { /* both are valid */
1226 if ((bootf1+1) == bootf2 || ((bootf1+1) >>2 == bootf2) ) nbootflag=1; /*bank2*/
1227 if ((bootf2+1) == bootf1 || ((bootf2+1) >>2 == bootf1) ) nbootflag=0; /*bank1*/
1229 else nbootflag = 0; /* bank2 invalid bank1 valid */
1231 else if ((bootf2 >> 2) == 0 && bootf2) nbootflag =1; /*bank 1 invalid,bank 2 valid*/
1232 else nbootflag=0; /* bank1 bank2 both invalid */
1234 //printf("bootf1 %x bootf2 %x\n", bootf1,bootf2);
1240 startblock = nbootflag?flash_get_blk(FLASH_BASE+(totalSize/2)):flash_get_blk(FLASH_BASE+FLASH_LENGTH_BOOT_ROM);
1241 //printk("bootbank %d,start to scan from %d block\n",startblock);
1243 // start from 2nd blk, assume 1st one is always CFE
1244 for (i = startblock; i < startblock + (totalBlks>>1) ; i++)
1246 sectAddr = flash_get_memptr((byte) i);
1247 crc = CRC32_INIT_VALUE;
1248 crc = getCrc32(sectAddr, (UINT32)TAG_LEN-TOKEN_LEN, crc);
1249 pTag = (PFILE_TAG) sectAddr;
1250 if (crc == (UINT32)(*(UINT32*)(pTag->tagValidationToken)))
1253 return (PFILE_TAG) NULL;
1258 #if defined(CONFIG_BCM96358)
1259 PFILE_TAG kerSysImageTagGet(void)
1261 return( getBootImageTag() );
1265 //********************************************************************************************
1266 // misc. ioctl calls come to here. (flash, led, reset, kernel memory access, etc.)
1267 //********************************************************************************************
1268 static int board_ioctl( struct inode *inode, struct file *flip,
1269 unsigned int command, unsigned long arg )
1272 BOARD_IOCTL_PARMS ctrlParms;
1273 unsigned char ucaMacAddr[NVRAM_MAC_ADDRESS_LEN];
1275 #if defined(CONFIG_BCM96338) || defined(CONFIG_BCM96348) || defined(CONFIG_BCM96358)
1276 int totalSize = flash_get_total_size();
1277 unsigned char nbootflag; /*vic add for bootflag check*/
1279 static unsigned char HasWriteBinfs=0;
1284 case BOARD_IOCTL_FLASH_INIT:
1285 // not used for now. kerSysBcmImageInit();
1288 case BOARD_IOCTL_FLASH_WRITE:
1289 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0)
1291 NVRAM_DATA SaveNvramData;
1292 PNVRAM_DATA pNvramData = (PNVRAM_DATA) get_nvram_start_addr();
1293 //swda add,05/11/2006
1294 #ifdef BACKUP_WLAN_SPROM
1295 char SaveNvramData_sprom[NVRAM_SPROM_TABLE_SIZE];
1298 char Serial_No[SN_SIZE];
1300 #ifdef DEFAULT_WLAN_WEP128
1301 char WEP128bit_key[WEP128KEY_SIZE];
1304 switch (ctrlParms.action)
1306 /*==== add by Andrew (2004/09/14)====*/
1307 #if defined(CFG_XFER_TO_FACDEFLT)
1309 ret = kerSysFactDefltSet(ctrlParms.string, ctrlParms.strLen, ctrlParms.offset);
1315 if (ctrlParms.offset == -1)
1316 ret = kerSysScratchPadClearAll();
1318 ret = kerSysScratchPadSet(ctrlParms.string, ctrlParms.buf, ctrlParms.offset);
1322 //swda add,11/30/2006
1323 //swda: Power Led flash red
1324 kerSysLedCtrl(kLedPower, kLedStateOff);//green off
1325 kerSysLedCtrl(kLedDiag, kLedStateOn);//red on
1326 kerSysSetUpgradeState(2); //upgrade configuration start
1328 ret = kerSysPersistentSet(ctrlParms.string, ctrlParms.strLen, ctrlParms.offset);
1329 //swda add,11/30/2006
1330 //swda: Power Led solid green
1331 kerSysSetUpgradeState(0);//upgrade configuration end
1332 if ( IsMultiConfig || (!boot_complete_flag) ) {
1333 kerSysLedCtrl(kLedDiag, kLedStateOn);//red on
1335 kerSysLedCtrl(kLedDiag, kLedStateOff);//red
1336 kerSysLedCtrl(kLedPower, kLedStateOn);//green
1342 if (ctrlParms.offset == 1024 + 10) {
1343 unsigned long memType=*(unsigned long *)ctrlParms.string;
1344 printk("set memtype %d\n",memType);
1345 kerSysMemoryTypeSet(FLASH_BASE,(char *) &memType, sizeof(int));
1347 else if (ctrlParms.offset == 1024 + 20) {
1348 unsigned long memType=*(unsigned long *)ctrlParms.string;
1349 printk("set Thread num %d\n");
1350 kerSysThreadNumSet(FLASH_BASE,(char *) &memType, sizeof(int));
1353 ret = kerSysNvRamSet(ctrlParms.string, ctrlParms.strLen, ctrlParms.offset);
1355 #if defined(CONFIG_BCM96348)
1356 case BCM_IMAGE_BINFS:
1358 //printk("will flash bin fs offset at 0%x\n",ctrlParms.offset);
1359 if ( totalSize < 8*1024*1024 ) {
1360 printk(" Bin file system only is allowed for 8MB not for %d MB Flash\n",flash_get_total_size()/0x100000);
1366 if( ctrlParms.strLen <= 0 || ctrlParms.strLen > 4*1024*1024 - 64*1024)
1368 printk("Illegal root file system size [%d]. Size allowed: [%d]\n",
1369 ctrlParms.strLen, allowedSize);
1373 //swda: Power Led flash red
1374 kerSysLedCtrl(kLedPower, kLedStateOff);//green
1375 kerSysLedCtrl(kLedDiag, kLedStateOn);//red
1376 kerSysSetUpgradeState(1); //upgrade start
1377 ret = kerSysBcmImageSet(ctrlParms.offset, ctrlParms.string, ctrlParms.strLen);
1378 //swda: Power Led solid green
1379 kerSysLedCtrl(kLedDiag, kLedStateOff);//red
1380 kerSysLedCtrl(kLedPower, kLedStateOn);//green
1381 kerSysSetUpgradeState(0);//upgrade end
1387 if( ctrlParms.strLen <= 0 || ctrlParms.strLen > FLASH_LENGTH_BOOT_ROM )
1389 printk("Illegal CFE size [%d]. Size allowed: [%d]\n",
1390 ctrlParms.strLen, FLASH_LENGTH_BOOT_ROM);
1394 #if defined(CONFIG_BCM96348) || defined(CONFIG_BCM96338) || defined(CONFIG_BCM96358)
1395 //swda: Power Led flash red
1396 kerSysLedCtrl(kLedPower, kLedStateOff);//green
1397 kerSysLedCtrl(kLedDiag, kLedStateOn);//red
1398 kerSysSetUpgradeState(1); //upgrade start
1400 // save NVRAM data into a local structure
1401 memcpy( &SaveNvramData, pNvramData, sizeof(NVRAM_DATA) );
1402 //swda add,05/11/2006
1403 #ifdef BACKUP_WLAN_SPROM //save NVRAM sprom data into a local structure
1404 kerSysNvRamGet(SaveNvramData_sprom, NVRAM_SPROM_TABLE_SIZE, NVRAM_SPROM_TABLE_OFFSET);
1406 //save Serial Number into a local structure
1407 kerSysNvRamGet(Serial_No, SN_SIZE, SN_OFFSET);
1409 #ifdef DEFAULT_WLAN_WEP128 //save WEP 128bit key into a local structure
1410 kerSysNvRamGet(WEP128bit_key,WEP128KEY_SIZE,WEP128KEY_OFFSET);
1413 // set memory type field
1414 BpGetSdramSize( (unsigned long *) &ctrlParms.string[SDRAM_TYPE_ADDRESS_OFFSET] );
1415 // set thread number field
1416 BpGetCMTThread( (unsigned long *) &ctrlParms.string[THREAD_NUM_ADDRESS_OFFSET] );
1418 ret = kerSysBcmImageSet(ctrlParms.offset + BOOT_OFFSET, ctrlParms.string, ctrlParms.strLen);
1420 // if nvram is not valid, restore the current nvram settings
1421 if( BpSetBoardId( pNvramData->szBoardId ) != BP_SUCCESS &&
1422 *(unsigned long *) pNvramData == NVRAM_DATA_ID )
1424 kerSysNvRamSet((char *) &SaveNvramData, sizeof(SaveNvramData), 0);
1426 //swda add,05/11/2006
1427 #ifdef BACKUP_WLAN_SPROM //swda : restore nvram sprom data
1428 kerSysNvRamSet(SaveNvramData_sprom, NVRAM_SPROM_TABLE_SIZE, NVRAM_SPROM_TABLE_OFFSET);
1431 //restore Serial Number
1432 kerSysNvRamSet(Serial_No, SN_SIZE, SN_OFFSET);
1434 #ifdef DEFAULT_WLAN_WEP128 //restore WEP 128bit key
1435 kerSysNvRamSet(WEP128bit_key,WEP128KEY_SIZE,WEP128KEY_OFFSET);
1438 #if defined(CONFIG_BCM96348) || defined(CONFIG_BCM96338) || defined(CONFIG_BCM96358)
1439 //swda: Power Led solid green
1440 kerSysLedCtrl(kLedDiag, kLedStateOff);//red
1441 kerSysLedCtrl(kLedPower, kLedStateOn);//green
1442 kerSysSetUpgradeState(0); //upgrade end
1447 #if 0 /* defined(CONFIG_BCM96358) */
1448 //swda: Power Led flash red
1449 kerSysLedCtrl(kLedPower, kLedStateOff);//green
1450 kerSysLedCtrl(kLedDiag, kLedStateOn);//red
1451 kerSysSetUpgradeState(1); //upgrade start
1453 if( (ret = flashFsKernelImage( ctrlParms.offset,
1454 ctrlParms.string, ctrlParms.strLen)) == 0 )
1456 //swda: Power Led solid green
1457 kerSysLedCtrl(kLedDiag, kLedStateOff);//red
1458 kerSysLedCtrl(kLedPower, kLedStateOn);//green
1459 kerSysSetUpgradeState(0); //upgrade end
1461 kerSysMipsSoftReset();
1465 allowedSize = (int) flash_get_total_size() - \
1466 FLASH_RESERVED_AT_END - TAG_LEN - FLASH45_LENGTH_BOOT_ROM;
1467 if( ctrlParms.strLen <= 0 || ctrlParms.strLen > allowedSize)
1469 printk("Illegal root file system size [%d]. Size allowed: [%d]\n",
1470 ctrlParms.strLen, allowedSize);
1475 //swda: Power Led flash red
1476 kerSysLedCtrl(kLedPower, kLedStateOff);//green
1477 kerSysLedCtrl(kLedDiag, kLedStateOn);//red
1478 kerSysSetUpgradeState(1); //upgrade start
1480 //printk("\nflash fs offset at 0%x\n",ctrlParms.offset);
1482 #if defined(CONFIG_BCM96348)
1484 unsigned char* bootflag;
1486 bootflag=flash_get_memptr((byte) 0);
1489 pTag = (PFILE_TAG) ctrlParms.string;
1490 //printk("got %s cur %s\n", pTag->FlashLayoutVersion,BCM_FLASH_LAYOUT_VER);
1491 tagVer = (u_int32_t) simple_strtoul(pTag->FlashLayoutVersion, NULL, 10);
1492 curVer = (u_int32_t) simple_strtoul(BCM_FLASH_LAYOUT_VER, NULL, 10);
1494 if (totalSize == 0x800000)
1495 if (curVer > 4 && tagVer < 5) { /* 5 start from 3.28u */
1496 printk("Not allow to downgrade to flash layout version less than 5\n");
1501 if (totalSize == 0x800000) {nbootflag=*bootflag;printk("\nget bootflag %d\n",*bootflag);}
1504 if (((curVer >= 4) && ( tagVer <4 )) || HasWriteBinfs ) { /* flash layout 3 -> 4 will knows dualimage@8M */
1505 printk("flash layout curVer %x tagVer %x\n", curVer,tagVer);
1506 /* ?? erase bootflag to avoid choose an broken partition to start */
1507 if (!HasWriteBinfs) { printk("Not "); kerSysErasePS1();}
1508 printk("Has Writtten Binfs\n");
1509 nbootflag=1; /* boot from bf800000 will flash bfc00000 */
1510 /* will erase bf800000 after image(bfc00000) upgrade successfully */
1513 /* nbootflag=1; FAKE!!!! always flash bfc00000 */
1515 /* bootflag is 0 means boot from bfc00000 will flash bf800000 */
1517 u_int32_t rootfs_addr,kernel_addr,tagCrc;
1518 //printk("rootfs addr %s kernelAddress %s\n", pTag->rootfsAddress,pTag->kernelAddress);
1519 rootfs_addr = (u_int32_t) simple_strtoul(pTag->rootfsAddress, NULL, 10);
1520 kernel_addr = (u_int32_t) simple_strtoul(pTag->kernelAddress, NULL, 10);
1521 //printk("rootfs addr %x kernelAddress %x\n", rootfs_addr,kernel_addr);
1522 rootfs_addr-=0x400000;
1523 sprintf(pTag->rootfsAddress,"%lu",(unsigned long) rootfs_addr);
1524 kernel_addr-=0x400000;
1525 sprintf(pTag->kernelAddress,"%lu",(unsigned long) kernel_addr);
1527 //printk("rootfs addr %x kernelAddress %x\n", rootfs_addr,kernel_addr);
1528 tagCrc = CRC32_INIT_VALUE;
1529 tagCrc = getCrc32((byte*)pTag, TAG_LEN-TOKEN_LEN, tagCrc);
1530 memcpy(pTag->tagValidationToken, (byte*)&tagCrc, CRC_LEN);
1531 ctrlParms.offset-=0x400000;
1535 else nbootflag=0; /* will flash bfc00000 if bootflag is 1(bf800000 is valid) or 2(binfs) or else */
1540 #if defined(CONFIG_BCM96338) || defined(CONFIG_BCM96358)
1543 unsigned char bootf1,bootf2;
1546 pTag = (PFILE_TAG) ctrlParms.string;
1547 printk("\nImagelen %d\n", ctrlParms.strLen);
1548 tagVer = (u_int32_t) simple_strtoul(pTag->FlashLayoutVersion, NULL, 10);
1549 curVer = (u_int32_t) simple_strtoul(BCM_FLASH_LAYOUT_VER, NULL, 10);
1551 #if defined(CONFIG_BCM96338)
1552 if (totalSize == 0x400000)
1554 #if defined(CONFIG_BCM96358)
1555 if (totalSize == 0x800000)
1557 if (curVer > 4 && tagVer < 5) { /* 5 start from 3.28u */
1558 printk("Not allow to downgrade to flash layout version less than 5\n");
1562 #if defined(CONFIG_BCM96338)
1563 if ((totalSize == 0x400000) && (ctrlParms.strLen <= (0x200000 - TAG_LEN - FLASH45_LENGTH_BOOT_ROM -1) ) ) { /* get bootflag to compare where to boot from */
1565 #if defined(CONFIG_BCM96358)
1566 if ((totalSize == 0x800000) && (ctrlParms.strLen <= (0x400000 - TAG_LEN - FLASH45_LENGTH_BOOT_ROM -1) ) ) { /* get bootflag to compare where to boot from */
1569 bootf1 = *(unsigned char*) (FLASH_BASE+(totalSize/2)-1); /*see design note 4MB flash layout*/
1570 bootf2 = *(unsigned char*) (FLASH_BASE+totalSize-FLASH_RESERVED_AT_END-1);
1571 if ((bootf1 >> 2) == 0 && bootf1 ) {
1572 if ((bootf2 >> 2) == 0 && bootf2 ) { /* both are valid */
1573 if ((bootf1+1) == bootf2 || ((bootf1+1) >>2 == bootf2) ) nbootflag=1; /*bank2*/
1574 if ((bootf2+1) == bootf1 || ((bootf2+1) >>2 == bootf1) ) nbootflag=0; /*bank1*/
1575 } else nbootflag = 0; /* bank2 invalid bank1 valid */
1576 } else if ((bootf2 >> 2) == 0 && bootf2) nbootflag =1; /*bank 1 invalid,bank 2 valid*/
1577 else nbootflag=0; /* bank1 bank2 both invalid */
1578 printk("\nbflag %x %x,bbank %d\n",bootf1,bootf2, nbootflag);
1579 } else { nbootflag=2; kerSysErasePS1(); }
1581 #if defined(CONFIG_BCM96338)
1582 if (totalSize == 0x400000)
1584 #if defined(CONFIG_BCM96358)
1585 if (totalSize == 0x800000)
1587 if ((curVer >= 4) && ( tagVer <4 )) { /* flash layout 3 -> 4 will knows dualimage@8M */
1588 printk("flash layout curVer %x tagVer %x\n", curVer,tagVer);
1589 /* ?? erase bootflag to avoid choose an broken partition to start */
1591 nbootflag=2; /* skip set bootflag for bank 2 */
1594 if (nbootflag==0) { /*boot from bank0 will flash bank1*/
1596 u_int32_t rootfs_addr,kernel_addr,tagCrc;
1598 //printk("rootfs addr %s kernelAddress %s\n", pTag->rootfsAddress,pTag->kernelAddress);
1599 rootfs_addr = (u_int32_t) simple_strtoul(pTag->rootfsAddress, NULL, 10);
1600 kernel_addr = (u_int32_t) simple_strtoul(pTag->kernelAddress, NULL, 10);
1601 //printk("rootfs addr %x kernelAddress %x\n", rootfs_addr,kernel_addr);
1603 // Update rootfsAddr to point to the second boot partition.
1604 sprintf(((PFILE_TAG) pTag)->kernelAddress, "%lu",
1605 (unsigned long) (kernel_addr+(totalSize/2)-FLASH_LENGTH_BOOT_ROM) );
1607 sprintf(((PFILE_TAG) pTag)->rootfsAddress, "%lu",
1608 (unsigned long) (rootfs_addr+(totalSize/2)-FLASH_LENGTH_BOOT_ROM));
1611 //printk("rootfs addr %x kernelAddress %x\n", rootfs_addr,kernel_addr);
1612 tagCrc = CRC32_INIT_VALUE;
1613 tagCrc = getCrc32((byte*)pTag, TAG_LEN-TOKEN_LEN, tagCrc);
1614 memcpy(pTag->tagValidationToken, (byte*)&tagCrc, CRC_LEN);
1615 ctrlParms.offset+=((totalSize/2)-FLASH_LENGTH_BOOT_ROM );
1617 } else if ( nbootflag ==1 ) nbootflag=0;
1620 ctrlParms.offset+= BOOT_OFFSET;
1621 printk("Flashing@0%8x\n",ctrlParms.offset);
1622 ret = kerSysBcmImageSet(ctrlParms.offset, ctrlParms.string, ctrlParms.strLen);
1624 #if defined(CONFIG_BCM96348)
1625 if (totalSize == 0x800000)
1626 if(HasWriteBinfs) kerSysBootFlagSet(0x02);
1627 else kerSysBootFlagSet(nbootflag);
1630 #if defined(CONFIG_BCM96338)
1631 if (totalSize == 0x400000 && (nbootflag<2) )
1632 kerSysBootFlagSet(nbootflag);
1635 #if defined(CONFIG_BCM96358)
1636 if (totalSize == 0x800000 && (nbootflag<2) )
1637 kerSysBootFlagSet(nbootflag);
1641 //swda: Power Led solid green
1642 kerSysLedCtrl(kLedDiag, kLedStateOff);//red
1643 kerSysLedCtrl(kLedPower, kLedStateOn);//green
1644 kerSysSetUpgradeState(0); //upgrade end
1645 kerSysMipsSoftReset();
1650 case BCM_IMAGE_KERNEL: // not used for now.
1652 case BCM_IMAGE_WHOLE:
1653 if(ctrlParms.strLen <= 0)
1655 printk("Illegal flash image size [%d].\n", ctrlParms.strLen);
1660 #if defined(CONFIG_BCM96348) || defined(CONFIG_BCM96338) || defined(CONFIG_BCM96358)
1661 //swda: Power Led flash red
1662 kerSysLedCtrl(kLedPower, kLedStateOff);//green
1663 kerSysLedCtrl(kLedDiag, kLedStateOn);//red
1664 kerSysSetUpgradeState(1); //upgrade start
1666 // save NVRAM data into a local structure
1667 memcpy( &SaveNvramData, pNvramData, sizeof(NVRAM_DATA) );
1668 //swda add,05/11/2006
1669 #ifdef BACKUP_WLAN_SPROM //save NVRAM sprom data into a local structure
1670 kerSysNvRamGet(SaveNvramData_sprom, NVRAM_SPROM_TABLE_SIZE, NVRAM_SPROM_TABLE_OFFSET);
1672 //save Serial Number into a local structure
1673 kerSysNvRamGet(Serial_No, SN_SIZE, SN_OFFSET);
1675 #ifdef DEFAULT_WLAN_WEP128 //save WEP 128bit key into a local structure
1676 kerSysNvRamGet(WEP128bit_key,WEP128KEY_SIZE,WEP128KEY_OFFSET);
1679 if (ctrlParms.offset == 0) {
1680 ctrlParms.offset = FLASH_BASE;
1682 ret = kerSysBcmImageSet(ctrlParms.offset, ctrlParms.string, ctrlParms.strLen);
1684 // if nvram is not valid, restore the current nvram settings
1685 if( BpSetBoardId( pNvramData->szBoardId ) != BP_SUCCESS &&
1686 *(unsigned long *) pNvramData == NVRAM_DATA_ID )
1688 kerSysNvRamSet((char *) &SaveNvramData, sizeof(SaveNvramData), 0);
1690 //swda add,05/11/2006
1691 #ifdef BACKUP_WLAN_SPROM //swda : restore nvram sprom data
1692 kerSysNvRamSet(SaveNvramData_sprom, NVRAM_SPROM_TABLE_SIZE, NVRAM_SPROM_TABLE_OFFSET);
1695 //restore Serial Number
1696 kerSysNvRamSet(Serial_No, SN_SIZE, SN_OFFSET);
1698 #ifdef DEFAULT_WLAN_WEP128 //restore WEP 128bit key
1699 kerSysNvRamSet(WEP128bit_key,WEP128KEY_SIZE,WEP128KEY_OFFSET);
1703 #if defined(CONFIG_BCM96348) || defined(CONFIG_BCM96338) || defined(CONFIG_BCM96358)
1704 //swda: Power Led solid green
1705 kerSysLedCtrl(kLedDiag, kLedStateOff);//red
1706 kerSysLedCtrl(kLedPower, kLedStateOn);//green
1707 kerSysSetUpgradeState(0); //upgrade end
1709 kerSysMipsSoftReset();
1714 printk("flash_ioctl_command: invalid command %d\n", ctrlParms.action);
1717 ctrlParms.result = ret;
1718 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
1724 case BOARD_IOCTL_FLASH_READ:
1725 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0)
1727 switch (ctrlParms.action)
1729 /*==== add by Andrew (2004/09/14)====*/
1730 #if defined(CFG_XFER_TO_FACDEFLT)
1732 ret = kerSysFactDefltGet(ctrlParms.string, ctrlParms.strLen, ctrlParms.offset);
1738 ret = kerSysScratchPadGet(ctrlParms.string, ctrlParms.buf, ctrlParms.offset);
1742 ret = kerSysPersistentGet(ctrlParms.string, ctrlParms.strLen, ctrlParms.offset);
1746 ret = kerSysNvRamGet(ctrlParms.string, ctrlParms.strLen, ctrlParms.offset);
1750 ret = kerSysFlashSizeGet();
1755 printk("Not supported. invalid command %d\n", ctrlParms.action);
1758 ctrlParms.result = ret;
1759 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
1765 case BOARD_IOCTL_GET_NR_PAGES:
1766 ctrlParms.result = nr_free_pages() + get_page_cache_size();
1767 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
1771 case BOARD_IOCTL_DUMP_ADDR:
1772 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0)
1774 dumpaddr( (unsigned char *) ctrlParms.string, ctrlParms.strLen );
1775 ctrlParms.result = 0;
1776 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
1783 case BOARD_IOCTL_SET_MEMORY:
1784 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0)
1786 unsigned long *pul = (unsigned long *) ctrlParms.string;
1787 unsigned short *pus = (unsigned short *) ctrlParms.string;
1788 unsigned char *puc = (unsigned char *) ctrlParms.string;
1789 switch( ctrlParms.strLen )
1792 *pul = (unsigned long) ctrlParms.offset;
1795 *pus = (unsigned short) ctrlParms.offset;
1798 *puc = (unsigned char) ctrlParms.offset;
1801 dumpaddr( (unsigned char *) ctrlParms.string, sizeof(long) );
1802 ctrlParms.result = 0;
1803 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
1810 case BOARD_IOCTL_MIPS_SOFT_RESET:
1811 kerSysMipsSoftReset();
1814 case BOARD_IOCTL_LED_CTRL:
1815 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0)
1817 kerSysLedCtrl((BOARD_LED_NAME)ctrlParms.strLen, (BOARD_LED_STATE)ctrlParms.offset);
1822 case BOARD_IOCTL_GET_ID:
1823 if (copy_from_user((void*)&ctrlParms, (void*)arg,
1824 sizeof(ctrlParms)) == 0)
1826 if( ctrlParms.string )
1828 char *p = (char *) get_system_type();
1829 if( strlen(p) + 1 < ctrlParms.strLen )
1830 ctrlParms.strLen = strlen(p) + 1;
1831 __copy_to_user(ctrlParms.string, p, ctrlParms.strLen);
1834 ctrlParms.result = 0;
1835 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms,
1836 sizeof(BOARD_IOCTL_PARMS));
1840 case BOARD_IOCTL_GET_MAC_ADDRESS:
1841 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0)
1843 ctrlParms.result = kerSysGetMacAddress( ucaMacAddr,
1846 if( ctrlParms.result == 0 )
1848 __copy_to_user(ctrlParms.string, ucaMacAddr,
1849 sizeof(ucaMacAddr));
1852 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms,
1853 sizeof(BOARD_IOCTL_PARMS));
1860 case BOARD_IOCTL_RELEASE_MAC_ADDRESS:
1861 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0)
1863 if (copy_from_user((void*)ucaMacAddr, (void*)ctrlParms.string, \
1864 NVRAM_MAC_ADDRESS_LEN) == 0)
1866 ctrlParms.result = kerSysReleaseMacAddress( ucaMacAddr );
1870 ctrlParms.result = -EACCES;
1873 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms,
1874 sizeof(BOARD_IOCTL_PARMS));
1881 case BOARD_IOCTL_GET_PSI_SIZE:
1882 ctrlParms.result = (int) g_pNvramInfo->ulPsiSize;
1883 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
1887 case BOARD_IOCTL_GET_SDRAM_SIZE:
1888 ctrlParms.result = (int) g_pNvramInfo->ulSdramSize;
1889 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
1893 case BOARD_IOCTL_GET_BASE_MAC_ADDRESS:
1894 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0)
1896 __copy_to_user(ctrlParms.string, g_pNvramInfo->ucaBaseMacAddr, NVRAM_MAC_ADDRESS_LEN);
1897 ctrlParms.result = 0;
1899 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms,
1900 sizeof(BOARD_IOCTL_PARMS));
1907 case BOARD_IOCTL_GET_CHIP_ID:
1908 ctrlParms.result = (int) (PERF->RevID & 0xFFFF0000) >> 16;
1909 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
1913 case BOARD_IOCTL_GET_NUM_ENET: {
1914 ETHERNET_MAC_INFO EnetInfos[BP_MAX_ENET_MACS];
1916 if (BpGetEthernetMacInfo(EnetInfos, BP_MAX_ENET_MACS) == BP_SUCCESS) {
1917 for( i = 0; i < BP_MAX_ENET_MACS; i++) {
1918 if (EnetInfos[i].ucPhyType != BP_ENET_NO_PHY) {
1922 ctrlParms.result = numeth;
1923 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
1932 case BOARD_IOCTL_GET_CFE_VER:
1933 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
1934 char *vertag = (char *)(FLASH_BASE + CFE_VERSION_OFFSET);
1935 if (ctrlParms.strLen < CFE_VERSION_SIZE) {
1936 ctrlParms.result = 0;
1937 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
1940 else if (strncmp(vertag, "cfe-v", 5)) { // no tag info in flash
1941 ctrlParms.result = 0;
1942 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
1946 ctrlParms.result = 1;
1947 __copy_to_user(ctrlParms.string, vertag+CFE_VERSION_MARK_SIZE, CFE_VERSION_SIZE);
1948 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
1957 case BOARD_IOCTL_GET_ENET_CFG:
1958 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
1959 ETHERNET_MAC_INFO EnetInfos[BP_MAX_ENET_MACS];
1960 if (BpGetEthernetMacInfo(EnetInfos, BP_MAX_ENET_MACS) == BP_SUCCESS) {
1961 if (ctrlParms.strLen == sizeof(EnetInfos)) {
1962 __copy_to_user(ctrlParms.string, EnetInfos, sizeof(EnetInfos));
1963 ctrlParms.result = 0;
1964 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
1979 #if defined (WIRELESS)
1980 case BOARD_IOCTL_GET_WLAN_ANT_INUSE:
1981 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
1982 unsigned short antInUse = 0;
1983 if (BpGetWirelessAntInUse(&antInUse) == BP_SUCCESS) {
1984 if (ctrlParms.strLen == sizeof(antInUse)) {
1985 __copy_to_user(ctrlParms.string, &antInUse, sizeof(antInUse));
1986 ctrlParms.result = 0;
1987 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
2002 case BOARD_IOCTL_SET_TRIGGER_EVENT:
2003 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
2004 BOARD_IOC *board_ioc = (BOARD_IOC *)flip->private_data;
2005 ctrlParms.result = -EFAULT;
2007 if (ctrlParms.strLen == sizeof(unsigned long)) {
2008 board_ioc->eventmask |= *((int*)ctrlParms.string);
2009 #if defined (WIRELESS)
2010 if((board_ioc->eventmask & SES_EVENTS)) {
2011 if(sesBtn_irq != BP_NOT_DEFINED) {
2012 BcmHalInterruptEnable(sesBtn_irq);
2013 ctrlParms.result = 0;
2018 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
2027 case BOARD_IOCTL_GET_TRIGGER_EVENT:
2028 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
2029 BOARD_IOC *board_ioc = (BOARD_IOC *)flip->private_data;
2030 if (ctrlParms.strLen == sizeof(unsigned long)) {
2031 __copy_to_user(ctrlParms.string, &board_ioc->eventmask, sizeof(unsigned long));
2032 ctrlParms.result = 0;
2033 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
2045 case BOARD_IOCTL_UNSET_TRIGGER_EVENT:
2046 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
2047 if (ctrlParms.strLen == sizeof(unsigned long)) {
2048 BOARD_IOC *board_ioc = (BOARD_IOC *)flip->private_data;
2049 board_ioc->eventmask &= (~(*((int*)ctrlParms.string)));
2050 ctrlParms.result = 0;
2051 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
2062 #if defined (WIRELESS)
2063 case BOARD_IOCTL_SET_SES_LED:
2064 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
2065 if (ctrlParms.strLen == sizeof(int)) {
2066 sesLed_ctrl(*(int*)ctrlParms.string);
2067 ctrlParms.result = 0;
2068 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
2081 case BOARD_IOCTL_SET_MONITOR_FD:
2082 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
2083 int fput_needed = 0;
2085 g_monitor_file = fget_light( ctrlParms.offset, &fput_needed );
2086 if( g_monitor_file ) {
2087 /* Hook this file descriptor's poll function in order to set
2088 * the exception descriptor when there is a change in link
2091 g_monitor_task = current;
2092 g_orig_fop_poll = g_monitor_file->f_op->poll;
2093 g_monitor_file->f_op->poll = kerSysMonitorPollHook;
2098 case BOARD_IOCTL_WAKEUP_MONITOR_TASK:
2099 kerSysWakeupMonitorTask();
2102 case BOARD_IOCTL_GET_VCOPE_GPIO:
2103 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
2104 ret = ((ctrlParms.result = BpGetVcopeGpio(ctrlParms.offset)) != BP_NOT_DEFINED) ? 0 : -EFAULT;
2105 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
2109 ctrlParms.result = BP_NOT_DEFINED;
2114 case BOARD_IOCTL_SET_CS_PAR:
2115 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
2116 ret = ConfigCs(&ctrlParms);
2117 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
2124 case BOARD_IOCTL_SET_PLL:
2125 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
2126 SetPll(ctrlParms.strLen, ctrlParms.offset);
2127 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
2135 case BOARD_IOCTL_SET_GPIO:
2136 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
2137 SetGpio(ctrlParms.strLen, ctrlParms.offset);
2138 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
2146 //swda add,02/04/2005
2147 case BOARD_IOCTL_GET_SERIAL_NUMBER:
2148 if(copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
2149 strncpy(ctrlParms.string, g_Serial_No, SN_SIZE);
2150 ctrlParms.strLen = SN_SIZE;
2151 ctrlParms.string[ctrlParms.strLen] = '\0';
2152 ctrlParms.result = 0;
2153 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
2160 #ifdef DEFAULT_WLAN_WEP128
2161 case BOARD_IOCTL_GET_WEP128_KEY:
2162 if(copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
2163 strncpy(ctrlParms.string, g_WEP128bit_key,WEP128KEY_SIZE);
2164 ctrlParms.strLen = WEP128KEY_SIZE;
2165 ctrlParms.string[ctrlParms.strLen] = '\0';
2166 ctrlParms.result = 0;
2167 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
2175 case BOARD_IOCTL_INFO_BOOT_COMPLETE:
2176 printk("board_ioctl: boot complete!\n");
2177 boot_complete_flag = 1;
2181 case BOARD_IOCTL_SET_LLL_TEST_LED:
2182 if(copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
2183 if (ctrlParms.offset==0) {
2184 LLLTestLedTimerDelete();//if timer already running, delete it
2185 kerSysLedCtrl( kLedPPP, kLedStateOff );
2186 } else if (ctrlParms.offset==1) {
2187 LLLTestLedTimerDelete();//if timer already running, delete it
2188 kerSysLedCtrl( kLedPPP, kLedStateOn );
2189 LLLTestLedTimerStart();//turn off LLL test led after 30 seconds
2190 } else if (ctrlParms.offset==2) {
2191 LLLTestLedTimerDelete();//if timer already running, delete it
2192 kerSysLedCtrl( kLedPPP, kLedStateFastBlinkContinues );
2193 LLLTestLedTimerStart();//turn off LLL test led after 30 seconds
2195 ctrlParms.result = 0;
2203 case BOARD_IOCTL_PSTNCALL:
2204 spin_lock(&pstn_spin_lock);
2205 ctrlParms.result = (int) PSTNComingCall;
2206 spin_unlock(&pstn_spin_lock);
2207 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
2210 case BOARD_IOCTL_OFFHOOK:
2211 spin_lock(&offhook_spin_lock);
2212 ctrlParms.result = (int) PSTNphone2OFFHOOK;
2213 spin_unlock(&offhook_spin_lock);
2214 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
2218 #if ODM_AUTO_PROVISION_LAN
2219 case BOARD_IOCTL_AUTO_PROVISION_LAN:
2220 ctrlParms.result = (int) autoprovisionlan;
2221 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
2226 #ifdef WLAN_ENABLE_CTRL_BUTTON
2227 case BOARD_IOCTL_WLAN_ENABLE_CTRL_BUTTON:
2228 if(copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
2229 if ( ctrlParms.strLen == GET_BOOT_COMPLETE_FLAG ) {
2230 ctrlParms.result = boot_complete_flag;
2231 } else if ( ctrlParms.strLen == GET_WLAN_ENABLE_GPIO_STATUS ) {
2232 ctrlParms.result = (GPIO->GPIOio & (unsigned int)GPIO_WLAN_ENABLE_STATE) ? 1 : 0;
2235 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
2243 //swda add,11/29/2006
2244 case BOARD_IOCTL_SET_VAR:
2245 if(copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
2246 if ( strcmp(ctrlParms.string,"MultiConfig")==0 ) {
2247 IsMultiConfig = ctrlParms.strLen;
2249 ctrlParms.result = 0;
2258 ctrlParms.result = 0;
2259 printk("board_ioctl: invalid command %x, cmd %d .\n",command,_IOC_NR(command));
2268 /***************************************************************************
2269 * SES Button ISR/GPIO/LED functions.
2270 ***************************************************************************/
2271 #if defined (WIRELESS)
2272 static irqreturn_t sesBtn_isr(int irq, void *dev_id, struct pt_regs *ptregs)
2274 unsigned long gpio_mask = GPIO_NUM_TO_MASK(sesBtn_gpio);
2275 volatile unsigned long *gpio_io_reg = &GPIO->GPIOio;
2277 #if !defined(CONFIG_BCM96338)
2278 if( (sesBtn_gpio & BP_GPIO_NUM_MASK) >= 32 )
2280 gpio_mask = GPIO_NUM_TO_MASK_HIGH(sesBtn_gpio);
2281 gpio_io_reg = &GPIO->GPIOio_high;
2285 if (!(*gpio_io_reg & gpio_mask)){
2286 wake_up_interruptible(&g_board_wait_queue);
2287 return IRQ_RETVAL(1);
2289 return IRQ_RETVAL(0);
2293 static void __init sesBtn_mapGpio()
2295 if( BpGetWirelessSesBtnGpio(&sesBtn_gpio) == BP_SUCCESS )
2297 printk("SES: Button GPIO 0x%x is enabled\n", sesBtn_gpio);
2301 static void __init sesBtn_mapIntr(int context)
2303 if( BpGetWirelessSesExtIntr(&sesBtn_irq) == BP_SUCCESS )
2305 printk("SES: Button Interrupt 0x%x is enabled\n", sesBtn_irq);
2310 sesBtn_irq += INTERRUPT_ID_EXTERNAL_0;
2312 if (BcmHalMapInterrupt((FN_HANDLER)sesBtn_isr, context, sesBtn_irq)) {
2313 printk("SES: Interrupt mapping failed\n");
2315 BcmHalInterruptEnable(sesBtn_irq);
2319 static unsigned int sesBtn_poll(struct file *file, struct poll_table_struct *wait)
2321 unsigned long gpio_mask = GPIO_NUM_TO_MASK(sesBtn_gpio);
2322 volatile unsigned long *gpio_io_reg = &GPIO->GPIOio;
2324 #if !defined(CONFIG_BCM96338)
2325 if( (sesBtn_gpio & BP_GPIO_NUM_MASK) >= 32 )
2327 gpio_mask = GPIO_NUM_TO_MASK_HIGH(sesBtn_gpio);
2328 gpio_io_reg = &GPIO->GPIOio_high;
2332 if (!(*gpio_io_reg & gpio_mask)){
2338 static ssize_t sesBtn_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
2340 volatile unsigned int event=0;
2343 unsigned long gpio_mask = GPIO_NUM_TO_MASK(sesBtn_gpio);
2344 volatile unsigned long *gpio_io_reg = &GPIO->GPIOio;
2346 #if !defined (CONFIG_BCM96338)
2347 if( (sesBtn_gpio & BP_GPIO_NUM_MASK) >= 32 )
2349 gpio_mask = GPIO_NUM_TO_MASK_HIGH(sesBtn_gpio);
2350 gpio_io_reg = &GPIO->GPIOio_high;
2354 if(*gpio_io_reg & gpio_mask){
2355 BcmHalInterruptEnable(sesBtn_irq);
2359 __copy_to_user((char*)buffer, (char*)&event, sizeof(event));
2360 BcmHalInterruptEnable(sesBtn_irq);
2361 count -= sizeof(event);
2362 buffer += sizeof(event);
2363 ret += sizeof(event);
2367 static void __init sesLed_mapGpio()
2369 if( BpGetWirelessSesBtnGpio(&sesLed_gpio) == BP_SUCCESS )
2371 printk("SES: LED GPIO 0x%x is enabled\n", sesBtn_gpio);
2375 static void sesLed_ctrl(int action)
2378 //char status = ((action >> 8) & 0xff); /* extract status */
2379 //char event = ((action >> 16) & 0xff); /* extract event */
2380 //char blinktype = ((action >> 24) & 0xff); /* extract blink type for SES_LED_BLINK */
2382 BOARD_LED_STATE led;
2384 if(sesLed_gpio == BP_NOT_DEFINED)
2387 action &= 0xff; /* extract led */
2389 //printk("blinktype=%d, event=%d, status=%d\n",(int)blinktype, (int)event, (int)status);
2394 //printk("SES: led on\n");
2398 //printk("SES: led blink\n");
2399 led = kLedStateSlowBlinkContinues;
2403 //printk("SES: led off\n");
2407 kerSysLedCtrl(kLedSes, led);
2410 static void __init ses_board_init()
2416 static void __exit ses_board_deinit()
2419 BcmHalInterruptDisable(sesBtn_irq);
2423 /***************************************************************************
2424 * Dying gasp ISR and functions.
2425 ***************************************************************************/
2426 #define KERSYS_DBG printk
2428 #if defined(CONFIG_BCM96348) || defined(CONFIG_BCM96338)
2429 /* The BCM6348 cycles per microsecond is really variable since the BCM6348
2430 * MIPS speed can vary depending on the PLL settings. However, an appoximate
2431 * value of 120 will still work OK for the test being done.
2433 #define CYCLE_PER_US 120
2434 #elif defined(CONFIG_BCM96358)
2435 #define CYCLE_PER_US 150
2437 #define DG_GLITCH_TO (100*CYCLE_PER_US)
2439 static void __init kerSysDyingGaspMapIntr()
2441 unsigned long ulIntr;
2443 if( BpGetAdslDyingGaspExtIntr( &ulIntr ) == BP_SUCCESS ) {
2444 BcmHalMapInterrupt((FN_HANDLER)kerSysDyingGaspIsr, 0, INTERRUPT_ID_DG);
2445 BcmHalInterruptEnable( INTERRUPT_ID_DG );
2449 void kerSysSetWdTimer(ulong timeUs)
2451 TIMER->WatchDogDefCount = timeUs * (FPERIPH/1000000);
2452 TIMER->WatchDogCtl = 0xFF00;
2453 TIMER->WatchDogCtl = 0x00FF;
2456 ulong kerSysGetCycleCount(void)
2462 __asm volatile("mfc0 %0, $9":"=d"(cnt));
2467 static Bool kerSysDyingGaspCheckPowerLoss(void)
2473 clk0 = kerSysGetCycleCount();
2482 clk1 = kerSysGetCycleCount(); /* time cleared */
2483 /* wait a little to get new reading */
2484 while ((kerSysGetCycleCount()-clk1) < CYCLE_PER_US*2)
2486 } while ((PERF->IrqStatus & (1 << (INTERRUPT_ID_DG - INTERNAL_ISR_TABLE_OFFSET))) && ((kerSysGetCycleCount() - clk0) < DG_GLITCH_TO));
2488 if (!(PERF->IrqStatus & (1 << (INTERRUPT_ID_DG - INTERNAL_ISR_TABLE_OFFSET)))) {
2489 BcmHalInterruptEnable( INTERRUPT_ID_DG );
2490 KERSYS_DBG(" - Power glitch detected. Duration: %ld us\n", (kerSysGetCycleCount() - clk0)/CYCLE_PER_US);
2497 static void kerSysDyingGaspShutdown( void )
2499 kerSysSetWdTimer(1000000);
2500 #if defined(CONFIG_BCM96348)
2501 PERF->blkEnables &= ~(EMAC_CLK_EN | USBS_CLK_EN | USBH_CLK_EN | SAR_CLK_EN);
2502 #elif defined(CONFIG_BCM96358)
2503 PERF->blkEnables &= ~(EMAC_CLK_EN | USBS_CLK_EN | SAR_CLK_EN);
2507 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
2508 static irqreturn_t kerSysDyingGaspIsr(int irq, void * dev_id, struct pt_regs * regs)
2510 static unsigned int kerSysDyingGaspIsr(void)
2513 struct list_head *pos;
2514 CB_DGASP_LIST *tmp = NULL, *dsl = NULL;
2516 if (kerSysDyingGaspCheckPowerLoss()) {
2517 #ifdef POWER_SAVING_DG
2518 GPIO->GPIODir_high |= GPIO_NUM_TO_MASK_HIGH(35);//set GPIO 35 as output
2519 GPIO->GPIOio_high &= (~GPIO_NUM_TO_MASK_HIGH(35));//pull GPIO 35 low to reset 5325 ethernet switch
2520 GPIO->GPIODir_high |= GPIO_NUM_TO_MASK_HIGH(36);//set GPIO 36 as output
2521 GPIO->GPIOio_high &= (~GPIO_NUM_TO_MASK_HIGH(36));//pull GPIO 36 low to reset dsp 6341
2522 //printk("GPIO->GPIODir_high=0x%X\n",GPIO->GPIODir_high);
2523 //printk("GPIO->GPIOio_high=0x%X\n",GPIO->GPIOio_high);
2525 /* first to turn off everything other than dsl */
2526 list_for_each(pos, &g_cb_dgasp_list_head->list) {
2527 tmp = list_entry(pos, CB_DGASP_LIST, list);
2528 if(strncmp(tmp->name, "dsl", 3)) {
2529 #if POWER_SAVING_DG //michaelc CSP#41165 patch
2530 (tmp->cb_dgasp_fn)(tmp->context);
2539 /* now send dgasp */
2541 (dsl->cb_dgasp_fn)(dsl->context);
2542 #if POWER_SAVING_DG //swda mark,06/15/2006
2543 /* reset and shutdown system */
2544 kerSysDyingGaspShutdown();
2546 // If power is going down, nothing should continue!
2552 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
2553 return( IRQ_HANDLED );
2559 static void __init kerSysInitDyingGaspHandler( void )
2561 CB_DGASP_LIST *new_node;
2563 if( g_cb_dgasp_list_head != NULL) {
2564 printk("Error: kerSysInitDyingGaspHandler: list head is not null\n");
2567 new_node= (CB_DGASP_LIST *)kmalloc(sizeof(CB_DGASP_LIST), GFP_KERNEL);
2568 memset(new_node, 0x00, sizeof(CB_DGASP_LIST));
2569 INIT_LIST_HEAD(&new_node->list);
2570 g_cb_dgasp_list_head = new_node;
2572 } /* kerSysInitDyingGaspHandler */
2574 static void __exit kerSysDeinitDyingGaspHandler( void )
2576 struct list_head *pos;
2579 if(g_cb_dgasp_list_head == NULL)
2582 list_for_each(pos, &g_cb_dgasp_list_head->list) {
2583 tmp = list_entry(pos, CB_DGASP_LIST, list);
2588 kfree(g_cb_dgasp_list_head);
2589 g_cb_dgasp_list_head = NULL;
2591 } /* kerSysDeinitDyingGaspHandler */
2593 void kerSysRegisterDyingGaspHandler(char *devname, void *cbfn, void *context)
2595 CB_DGASP_LIST *new_node;
2597 if( g_cb_dgasp_list_head == NULL) {
2598 printk("Error: kerSysRegisterDyingGaspHandler: list head is null\n");
2602 if( devname == NULL || cbfn == NULL ) {
2603 printk("Error: kerSysRegisterDyingGaspHandler: register info not enough (%s,%x,%x)\n", devname, (unsigned int)cbfn, (unsigned int)context);
2607 new_node= (CB_DGASP_LIST *)kmalloc(sizeof(CB_DGASP_LIST), GFP_KERNEL);
2608 memset(new_node, 0x00, sizeof(CB_DGASP_LIST));
2609 INIT_LIST_HEAD(&new_node->list);
2610 strncpy(new_node->name, devname, IFNAMSIZ);
2611 new_node->cb_dgasp_fn = (cb_dgasp_t)cbfn;
2612 new_node->context = context;
2613 list_add(&new_node->list, &g_cb_dgasp_list_head->list);
2615 printk("dgasp: kerSysRegisterDyingGaspHandler: %s registered \n", devname);
2617 } /* kerSysRegisterDyingGaspHandler */
2619 void kerSysDeregisterDyingGaspHandler(char *devname)
2621 struct list_head *pos;
2624 if(g_cb_dgasp_list_head == NULL) {
2625 printk("Error: kerSysDeregisterDyingGaspHandler: list head is null\n");
2629 if(devname == NULL) {
2630 printk("Error: kerSysDeregisterDyingGaspHandler: devname is null\n");
2634 printk("kerSysDeregisterDyingGaspHandler: %s is deregistering\n", devname);
2636 list_for_each(pos, &g_cb_dgasp_list_head->list) {
2637 tmp = list_entry(pos, CB_DGASP_LIST, list);
2638 if(!strcmp(tmp->name, devname)) {
2641 printk("kerSysDeregisterDyingGaspHandler: %s is deregistered\n", devname);
2645 printk("kerSysDeregisterDyingGaspHandler: %s not (de)registered\n", devname);
2647 } /* kerSysDeregisterDyingGaspHandler */
2649 static int ConfigCs (BOARD_IOCTL_PARMS *parms)
2652 #if !defined(CONFIG_BCM96338)
2654 cs_config_pars_t info;
2656 if (copy_from_user(&info, (void*)parms->buf, sizeof(cs_config_pars_t)) == 0)
2660 MPI->cs[cs].base = ((info.base & 0x1FFFE000) | (info.size >> 13));
2662 if ( info.mode == EBI_TS_TA_MODE ) // syncronious mode
2663 flags = (EBI_TS_TA_MODE | EBI_ENABLE);
2666 flags = ( EBI_ENABLE | \
2667 (EBI_WAIT_STATES & (info.wait_state << EBI_WTST_SHIFT )) | \
2668 (EBI_SETUP_STATES & (info.setup_time << EBI_SETUP_SHIFT)) | \
2669 (EBI_HOLD_STATES & (info.hold_time << EBI_HOLD_SHIFT )) );
2671 MPI->cs[cs].config = flags;
2672 parms->result = BP_SUCCESS;
2678 parms->result = BP_NOT_DEFINED;
2684 static void SetPll (int pll_mask, int pll_value)
2686 PERF->pll_control &= ~pll_mask; // clear relevant bits
2687 PERF->pll_control |= pll_value; // and set desired value
2690 static void SetGpio(int gpio, GPIO_STATE_t state)
2692 unsigned long gpio_mask = GPIO_NUM_TO_MASK(gpio);
2693 volatile unsigned long *gpio_io_reg = &GPIO->GPIOio;
2694 volatile unsigned long *gpio_dir_reg = &GPIO->GPIODir;
2696 #if !defined (CONFIG_BCM96338)
2699 gpio_mask = GPIO_NUM_TO_MASK_HIGH(gpio);
2700 gpio_io_reg = &GPIO->GPIOio_high;
2701 gpio_dir_reg = &GPIO->GPIODir_high;
2705 *gpio_dir_reg |= gpio_mask;
2707 if(state == GPIO_HIGH)
2708 *gpio_io_reg |= gpio_mask;
2710 *gpio_io_reg &= ~gpio_mask;
2714 static irqreturn_t reset_isr(int irq, void *dev_id, struct pt_regs *ptregs)
2716 printk("\n*** Restore to Factory Default Setting ***\n\n");
2717 kerSysPersistentSet( "Reset Persistent", strlen("Reset Persistent"), 0 );
2718 kerSysMipsSoftReset();
2723 //swda add,05/10/2006
2724 #ifdef BACKUP_WLAN_SPROM
2725 void kerSysGetSpromSavedFlag(unsigned char *pspromsavedflag)
2727 //PNVRAM_DATA pNvramData = (PNVRAM_DATA) get_nvram_start_addr();
2728 //*pspromsavedflag = pNvramData->sprom_saved_flag;
2729 //srom save flag has been read in InitNvramInfo
2730 *pspromsavedflag = g_SROMSaveFlag;
2732 void kerSysSetSpromSavedFlag(unsigned char spromsavedflag)
2734 PNVRAM_DATA pNvramData = (PNVRAM_DATA) get_nvram_start_addr();
2735 NVRAM_DATA SaveNvramData;
2736 UINT32 crc = CRC32_INIT_VALUE;
2738 // save NVRAM data into a local structure
2739 memcpy( &SaveNvramData, pNvramData, sizeof(NVRAM_DATA) );
2740 SaveNvramData.sprom_saved_flag = spromsavedflag;
2742 //write the nvramData struct to nvram after CRC is calculated
2743 SaveNvramData.ulCheckSum = 0;
2744 crc = getCrc32((char *)&SaveNvramData, (UINT32) sizeof(NVRAM_DATA), crc);
2745 SaveNvramData.ulCheckSum = crc;
2746 kerSysNvRamSet((char *) &SaveNvramData, sizeof(SaveNvramData), 0);
2748 void kerSysGetSpromTable(char *pspromdata,int size,int offset)
2750 //kerSysNvRamGet(pspromdata, size, offset);
2751 //SPROM has been read in InitNvramInfo
2752 memcpy(pspromdata,g_SPROMData,NVRAM_SPROM_TABLE_SIZE);
2754 void kerSysSetSpromTable(char *pspromdata,int size,int offset)
2756 kerSysNvRamSet(pspromdata, size, offset);
2758 #endif //BACKUP_WLAN_SPROM
2760 int kerSysSetUpgradeState(int state)
2762 is_update_flash = state;
2764 int kerSysGetUpgradeState(void)
2766 return is_update_flash;
2770 /***************************************************************************
2771 * MACRO to call driver initialization and cleanup functions.
2772 ***************************************************************************/
2773 module_init( brcm_board_init );
2774 module_exit( brcm_board_cleanup );
2776 EXPORT_SYMBOL(kerSysNvRamGet);
2777 EXPORT_SYMBOL(dumpaddr);
2778 EXPORT_SYMBOL(kerSysGetMacAddress);
2779 EXPORT_SYMBOL(kerSysReleaseMacAddress);
2780 EXPORT_SYMBOL(kerSysGetSdramSize);
2781 EXPORT_SYMBOL(kerSysLedCtrl);
2782 EXPORT_SYMBOL(kerSysLedRegisterHwHandler);
2783 EXPORT_SYMBOL(BpGetBoardIds);
2784 EXPORT_SYMBOL(BpGetSdramSize);
2785 EXPORT_SYMBOL(BpGetPsiSize);
2786 EXPORT_SYMBOL(BpGetEthernetMacInfo);
2787 EXPORT_SYMBOL(BpGetRj11InnerOuterPairGpios);
2788 EXPORT_SYMBOL(BpGetPressAndHoldResetGpio);
2789 EXPORT_SYMBOL(BpGetVoipResetGpio);
2790 EXPORT_SYMBOL(BpGetVoipIntrGpio);
2791 EXPORT_SYMBOL(BpGetRtsCtsUartGpios);
2792 EXPORT_SYMBOL(BpGetAdslLedGpio);
2793 EXPORT_SYMBOL(BpGetAdslFailLedGpio);
2794 EXPORT_SYMBOL(BpGetWirelessLedGpio);
2795 EXPORT_SYMBOL(BpGetUsbLedGpio);
2796 EXPORT_SYMBOL(BpGetHpnaLedGpio);
2797 EXPORT_SYMBOL(BpGetWanDataLedGpio);
2798 EXPORT_SYMBOL(BpGetPppLedGpio);
2799 EXPORT_SYMBOL(BpGetPppFailLedGpio);
2800 EXPORT_SYMBOL(BpGetVoipLedGpio);
2801 EXPORT_SYMBOL(BpGetAdslDyingGaspExtIntr);
2802 EXPORT_SYMBOL(BpGetVoipExtIntr);
2803 EXPORT_SYMBOL(BpGetHpnaExtIntr);
2804 EXPORT_SYMBOL(BpGetHpnaChipSelect);
2805 EXPORT_SYMBOL(BpGetVoipChipSelect);
2806 EXPORT_SYMBOL(BpGetWirelessSesBtnGpio);
2807 EXPORT_SYMBOL(BpGetWirelessSesExtIntr);
2808 EXPORT_SYMBOL(BpGetWirelessSesLedGpio);
2809 EXPORT_SYMBOL(BpGetWirelessFlags);
2810 EXPORT_SYMBOL(kerSysRegisterDyingGaspHandler);
2811 EXPORT_SYMBOL(kerSysDeregisterDyingGaspHandler);
2812 EXPORT_SYMBOL(kerSysGetCycleCount);
2813 EXPORT_SYMBOL(kerSysSetWdTimer);
2814 EXPORT_SYMBOL(kerSysWakeupMonitorTask);
2815 #ifdef BACKUP_WLAN_SPROM
2816 EXPORT_SYMBOL(kerSysGetSpromSavedFlag);
2817 EXPORT_SYMBOL(kerSysSetSpromSavedFlag);
2818 EXPORT_SYMBOL(kerSysGetSpromTable);
2819 EXPORT_SYMBOL(kerSysSetSpromTable);
2821 EXPORT_SYMBOL(kerSysGetUpgradeState);//swda add,06/27/2006