http://downloads.netgear.com/files/GPL/GPL_Source_V361j_DM111PSP_series_consumer_rele...
[bcm963xx.git] / bcmdrivers / opensource / char / board / bcm963xx / impl1 / board.c
1 /*
2 <:copyright-gpl 
3  Copyright 2002 Broadcom Corp. All Rights Reserved. 
4  
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. 
8  
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 
12  for more details. 
13  
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. 
17 :>
18 */
19 /***************************************************************************
20  * File Name  : board.c
21  *
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.
25  *
26  *
27  ***************************************************************************/
28
29 /* Includes. */
30 #include <linux/version.h>
31 #include <linux/init.h>
32 #include <linux/fs.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>
44 #include <linux/if.h>
45
46 #include <bcm_map_part.h>
47 #include <board.h>
48 #include <bcmTag.h>
49 #include "boardparms.h"
50 #include "flash_api.h"
51 #include "bcm_intr.h"
52 #include "board.h"
53 #include "bcm_map_part.h"
54
55 /* Typedefs. */
56
57 #if defined (WIRELESS)
58 #define SES_BTN_PRESSED 0x00000001
59 #define SES_EVENTS      SES_BTN_PRESSED /*OR all values if any*/
60 #define SES_LED_OFF     0
61 #define SES_LED_ON      1
62 #define SES_LED_BLINK   2
63 #endif
64
65 typedef struct
66 {
67     unsigned long ulId;
68     char chInUse;
69     char chReserved[3];
70 } MAC_ADDR_INFO, *PMAC_ADDR_INFO;
71
72 typedef struct
73 {
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;
80
81 typedef struct
82 {
83     unsigned long eventmask;    
84 } BOARD_IOC, *PBOARD_IOC;
85
86
87 /*Dyinggasp callback*/
88 typedef void (*cb_dgasp_t)(void *arg);
89 typedef struct _CB_DGASP__LIST
90 {
91     struct list_head list;
92     char name[IFNAMSIZ];
93     cb_dgasp_t cb_dgasp_fn;
94     void *context;
95 }CB_DGASP_LIST , *PCB_DGASP_LIST;
96
97
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.
110 };
111
112 /* Externs. */
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);
125
126 /* Prototypes. */
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);                        
133
134 static BOARD_IOC* borad_ioc_alloc(void);
135 static void borad_ioc_free(BOARD_IOC* board_ioc);
136
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);
141 #else
142 static unsigned int kerSysDyingGaspIsr(void);
143 #endif
144 static void __init kerSysInitDyingGaspHandler( void );
145 static void __exit kerSysDeinitDyingGaspHandler( void );
146 /* -DyingGasp function prototype - */
147
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);
151
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);
162 #endif
163
164 static irqreturn_t reset_isr(int irq, void *dev_id, struct pt_regs *ptregs);
165
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;
170
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;
176
177 static struct file_operations board_fops =
178 {
179   open:       board_open,
180   ioctl:      board_ioctl,
181   poll:       board_poll,
182   read:       board_read,
183   release:    board_release,
184 };
185
186 uint32 board_major = 0;
187
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;
192 #endif
193
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;
200 #endif
201
202 #define SN_OFFSET       680
203 #define SN_SIZE 31
204 static char g_Serial_No[SN_SIZE];
205
206 #ifdef  DEFAULT_WLAN_WEP128
207 #define WEP128KEY_OFFSET        712
208 #define WEP128KEY_SIZE          13
209 static char g_WEP128bit_key[WEP128KEY_SIZE];
210 #endif
211
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       
216 #endif
217 int is_update_flash = 0;
218 int IsMultiConfig = 0;
219 //swda add end
220
221 #if defined(MODULE)
222 int init_module(void)
223 {
224     return( brcm_board_init() );              
225 }
226
227 void cleanup_module(void)
228 {
229     if (MOD_IN_USE)
230         printk("brcm flash: cleanup_module failed because module is in use\n");
231     else
232         brcm_board_cleanup();
233 }
234 #endif //MODULE 
235
236 /* Reset to default */
237 #define K100MS                  ((100 * HZ) / 1000)     // ~100 ms
238 #define DURATION                3*HZ                    //about 3 seconds
239 // global variables:
240 struct timer_list gMonitorTimerRST;
241 int gMonitorTimerOnRST = FALSE;
242 void MonitorTimerExpireRST(void);
243 unsigned long PressTime = DURATION;
244
245 #if VOXXXLOAD
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;
254 int pstn_spin_lock;
255 int offhook_spin_lock;
256 unsigned long NoActionTimePSTN=0;
257 unsigned long NoActionTimeOFFHOOK=0;
258 #endif
259
260 #if ODM_AUTO_PROVISION_LAN
261 int autoprovisionlan=0;
262 #endif
263
264 int boot_complete_flag = 0;
265
266
267 void MonitorTimerStartRST(void)
268 {
269 #if defined(CONFIG_BCM96358)||defined(CONFIG_BCM96348)||defined(CONFIG_BCM96338)
270     if (gMonitorTimerOnRST)
271         return;
272
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;
278 #endif
279 }
280
281 void MonitorTimerExpireRST(void)
282 {
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
292 #ifdef WESTELL_GPIO
293         //printk("PERF->ExtIrqCfg = %X\n",PERF->ExtIrqCfg);
294         if ( !(PERF->ExtIrqCfg & 0x00000020) ) {
295 #else
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)) {
299 #endif
300 #endif
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();
309                         } else {
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)
313                 autoprovisionlan=1;
314                 }
315 #else
316             printk("\nReset to factory default setting...\n");
317             kerSysErasePersistent();
318             //flash_reset();
319             //setDefaultBootline();
320             kerSysMipsSoftReset();
321 #endif
322             gMonitorTimerOnRST = TRUE;
323             return;
324         }
325     } else {
326         PressTime = 0;
327     }
328
329     gMonitorTimerOnRST = FALSE;
330     MonitorTimerStartRST();
331 }
332
333 #if VOXXXLOAD
334 void MonitorTimerStartPSTN(void)
335 {
336 #if defined(CONFIG_BCM96345)||defined(CONFIG_BCM96348)
337     if (gMonitorTimerOnPSTN)
338         return;
339
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;
345 #endif
346 }
347
348 void MonitorTimerExpirePSTN(void)
349 {
350 #if defined(CONFIG_BCM96345)
351   #define GPIO_PSTN   0x0200
352     if (GPIO->GPIOio & (unsigned short)GPIO_PSTN){
353 #else
354   #define GPIO_PSTN   0x800000
355     if (GPIO->GPIOio & (unsigned int)GPIO_PSTN){
356 #endif
357        if(!PSTNComingCall) {
358            spin_lock(&pstn_spin_lock);
359            //printk("**PSTN incoming call\n");
360            PSTNComingCall=1;
361            spin_unlock(&pstn_spin_lock);
362        }
363        NoActionTimePSTN=0;
364        //printk("                                  **PSTN incoming call\n");
365     } else {
366        NoActionTimePSTN++;
367        if(NoActionTimePSTN>50) {
368              NoActionTimePSTN=0;
369              if(PSTNComingCall) {
370                spin_lock(&pstn_spin_lock);
371                //printk("**No PSTN incoming call\n");
372                PSTNComingCall=0;
373                spin_unlock(&pstn_spin_lock);
374              }
375         }
376         //printk("                                            *NO PSTN incoming call signal\n");
377      }
378     gMonitorTimerOnPSTN = FALSE;
379     MonitorTimerStartPSTN();
380 }
381
382 void MonitorTimerStartOFFHOOK(void)
383 {
384     if (gMonitorTimerOnOFFHOOK)
385         return;
386
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;
392 }
393
394 void MonitorTimerExpireOFFHOOK(void)
395 {
396 #if defined(CONFIG_BCM96345)
397   #define GPIO_OFFHOOK   0x0002
398     if (!(GPIO->GPIOio & (unsigned short)GPIO_OFFHOOK)){
399 #else
400   #define GPIO_OFFHOOK   0x400000
401     if (!(GPIO->GPIOio & (unsigned int)GPIO_OFFHOOK)){
402 #endif 
403        if((!PSTNphone2OFFHOOK)&&(!PSTNComingCall)) {
404            spin_lock(&offhook_spin_lock);
405           // printk("**PSTN OFFHOOK\n");
406            PSTNphone2OFFHOOK=1;
407            spin_unlock(&offhook_spin_lock);
408        }
409        NoActionTimeOFFHOOK=0;
410     //printk("**PSTN OFFHOOK\n");
411     } else {
412        NoActionTimeOFFHOOK++;
413        if(NoActionTimeOFFHOOK>20) {
414              NoActionTimeOFFHOOK=0;
415              if(PSTNphone2OFFHOOK) {
416                spin_lock(&offhook_spin_lock);
417                //printk("**No PSTN OFFHOOK\n");
418                PSTNphone2OFFHOOK=0;
419                spin_unlock(&offhook_spin_lock);
420              }
421         }
422      //printk("              **PSTN ONHOOK\n");
423      }
424     gMonitorTimerOnOFFHOOK = FALSE;
425     MonitorTimerStartOFFHOOK();
426 }
427 #endif  //VOXXXLOAD
428
429 //swda add,11/02/2005
430 #ifdef  LLL_TEST_LED
431 struct timer_list gLLLTestLedTimer;
432 static int gLLLTestLedTimerRunning = 0;
433
434 void LLLTestLedTimerExpireFunc(void)
435 {
436         kerSysLedCtrl( kLedPPP, kLedStateOff );
437         gLLLTestLedTimerRunning = 0;    
438 }
439 void LLLTestLedTimerStart(void)
440 {
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;        
446 }
447 void LLLTestLedTimerDelete(void)
448 {
449         if (gLLLTestLedTimerRunning ) {
450                 del_timer(&gLLLTestLedTimer);
451                 gLLLTestLedTimerRunning = 0;
452         }
453 }
454 #endif
455 //swda add end
456
457 static int __init brcm_board_init( void )
458 {
459     typedef int (*BP_LED_FUNC) (unsigned short *);
460     static struct BpLedInformation
461     {
462         BOARD_LED_NAME ledName;
463         BP_LED_FUNC bpFunc;
464         BP_LED_FUNC bpFuncFail;
465     } bpLedInfo[] =
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}
477     };
478
479     unsigned short pah_irq;     
480     int ret;
481         
482     ret = register_chrdev(BOARD_DRV_MAJOR, "bcrmboard", &board_fops );
483     if (ret < 0)
484         printk( "brcm_board_init(major %d): fail to register device.\n",BOARD_DRV_MAJOR);
485     else 
486     {
487         PLED_MAP_PAIR pLedMap = LedMapping;
488         unsigned short gpio;
489         struct BpLedInformation *pInfo;
490         ETHERNET_MAC_INFO EnetInfo;
491
492         printk("brcmboard: brcm_board_init entry\n");
493         board_major = BOARD_DRV_MAJOR;
494         InitNvramInfo();
495
496         for( pInfo = bpLedInfo; pInfo->ledName != kLedEnd; pInfo++ )
497         {
498             if( pInfo->bpFunc && (*pInfo->bpFunc) (&gpio) == BP_SUCCESS &&
499                 gpio != BP_HW_DEFINED_AH && gpio != BP_HW_DEFINED_AL )
500             {
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;
510                 //swda add end
511             }
512             if( pInfo->bpFuncFail && (*pInfo->bpFuncFail)(&gpio)==BP_SUCCESS &&
513                 gpio != BP_HW_DEFINED_AH && gpio != BP_HW_DEFINED_AL )
514             {
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;
519             }
520             if( pLedMap->ledName != kLedEnd )
521                 pLedMap++;
522         }
523         
524         if( BpGetEthernetMacInfo( &EnetInfo, 1 ) == BP_SUCCESS )
525         {
526             if( EnetInfo.usGpioPhyLinkSpeed != BP_NOT_DEFINED )
527             {
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;
534                 pLedMap++;
535             }
536         }
537         
538         init_waitqueue_head(&g_board_wait_queue);
539 #if defined (WIRELESS)
540         ses_board_init();
541 #endif        
542         kerSysInitDyingGaspHandler();
543         kerSysDyingGaspMapIntr();
544
545         boardLedInit(LedMapping);
546         g_ledInitialized = 1;
547
548         if( BpGetPressAndHoldResetExtIntr(&pah_irq) == BP_SUCCESS )
549         {
550             pah_irq += INTERRUPT_ID_EXTERNAL_0; 
551             BcmHalMapInterrupt((FN_HANDLER)reset_isr, 0, pah_irq);
552             BcmHalInterruptEnable(pah_irq);
553         }
554     }
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
558          
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
561 #endif
562
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
566 #endif
567
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
570 #endif
571
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
574 #endif
575
576     MonitorTimerStartRST();
577 #if VOXXXLOAD
578     MonitorTimerStartPSTN();
579     MonitorTimerStartOFFHOOK();
580 #endif
581
582     return ret;
583
584
585 void __init InitNvramInfo( void )
586 {
587     PNVRAM_DATA pNvramData = (PNVRAM_DATA) get_nvram_start_addr();
588 #if 0 //BRCM orig
589     unsigned long ulNumMacAddrs = pNvramData->ulNumMacAddrs;
590 #else
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 */
592 #endif
593     if( ulNumMacAddrs > 0 && ulNumMacAddrs <= NVRAM_MAC_COUNT_MAX )
594     {
595         unsigned long ulNvramInfoSize =
596             sizeof(NVRAM_INFO) + ((sizeof(MAC_ADDR_INFO) - 1) * ulNumMacAddrs);
597
598         g_pNvramInfo = (PNVRAM_INFO) kmalloc( ulNvramInfoSize, GFP_KERNEL );
599
600         if( g_pNvramInfo )
601         {
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;
607 #if 0 //BRCM orig
608             g_pNvramInfo->ulNumMacAddrs = pNvramData->ulNumMacAddrs;
609 #else
610             g_pNvramInfo->ulNumMacAddrs = 12;
611 #endif
612             memcpy( g_pNvramInfo->ucaBaseMacAddr, pNvramData->ucaBaseMacAddr,
613                 NVRAM_MAC_ADDRESS_LEN );
614             g_pNvramInfo->ulSdramSize = getMemorySize();
615         }
616         else
617             printk("ERROR - Could not allocate memory for NVRAM data\n");
618     }
619     else
620         printk("ERROR - Invalid number of MAC addresses (%ld) is configured.\n",
621             ulNumMacAddrs);
622
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);
627 #endif
628
629         kerSysNvRamGet(g_Serial_No, SN_SIZE, SN_OFFSET);
630
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;
635                 
636                 valid_key = 1;
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 ) {
640                                 valid_key = 0;
641                                 break;
642                         }       
643                 }
644                 if (!valid_key) 
645                         strcpy(g_WEP128bit_key,"0000000000000");        
646         }
647 #endif
648 //swda add end
649 }
650
651 void __exit brcm_board_cleanup( void )
652 {
653     printk("brcm_board_cleanup()\n");
654         
655     if (board_major != -1) 
656     {
657 #if defined (WIRELESS)          
658         ses_board_deinit();
659 #endif          
660         kerSysDeinitDyingGaspHandler();
661         unregister_chrdev(board_major, "board_ioctl");
662     }
663
664
665 static BOARD_IOC* borad_ioc_alloc(void)
666 {
667     BOARD_IOC *board_ioc =NULL;
668     board_ioc = (BOARD_IOC*) kmalloc( sizeof(BOARD_IOC) , GFP_KERNEL );
669     if(board_ioc)
670     {
671         memset(board_ioc, 0, sizeof(BOARD_IOC));
672     }
673     return board_ioc;
674 }
675
676 static void borad_ioc_free(BOARD_IOC* board_ioc)
677 {
678     if(board_ioc)
679     {
680         kfree(board_ioc);
681     }   
682 }
683
684
685 static int board_open( struct inode *inode, struct file *filp )
686 {
687     filp->private_data = borad_ioc_alloc();
688
689     if (filp->private_data == NULL)
690         return -ENOMEM;
691             
692     return( 0 );
693
694
695 static int board_release(struct inode *inode, struct file *filp)
696 {
697     BOARD_IOC *board_ioc = filp->private_data;
698     
699     wait_event_interruptible(g_board_wait_queue, 1);    
700     borad_ioc_free(board_ioc);
701
702     return( 0 );
703
704
705
706 static unsigned int board_poll(struct file *filp, struct poll_table_struct *wait)
707 {
708     unsigned int mask = 0;
709 #if defined (WIRELESS)          
710     BOARD_IOC *board_ioc = filp->private_data;          
711 #endif
712         
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);
717     }                   
718 #endif    
719
720     return mask;
721 }
722
723
724 static ssize_t board_read(struct file *filp,  char __user *buffer, size_t count, loff_t *ppos)
725 {
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);
730     }
731 #endif    
732     return 0;
733 }
734
735 //**************************************************************************************
736 // Utitlities for dump memory, free kernel pages, mips soft reset, etc.
737 //**************************************************************************************
738
739 /***********************************************************************
740  * Function Name: dumpaddr
741  * Description  : Display a hex dump of the specified address.
742  ***********************************************************************/
743 void dumpaddr( unsigned char *pAddr, int nLen )
744 {
745     static char szHexChars[] = "0123456789abcdef";
746     char szLine[80];
747     char *p = szLine;
748     unsigned char ch, *q;
749     int i, j;
750     unsigned long ul;
751
752     while( nLen > 0 )
753     {
754         sprintf( szLine, "%8.8lx: ", (unsigned long) pAddr );
755         p = szLine + strlen(szLine);
756
757         for(i = 0; i < 16 && nLen > 0; i += sizeof(long), nLen -= sizeof(long))
758         {
759             ul = *(unsigned long *) &pAddr[i];
760             q = (unsigned char *) &ul;
761             for( j = 0; j < sizeof(long); j++ )
762             {
763                 *p++ = szHexChars[q[j] >> 4];
764                 *p++ = szHexChars[q[j] & 0x0f];
765                 *p++ = ' ';
766             }
767         }
768
769         for( j = 0; j < 16 - i; j++ )
770             *p++ = ' ', *p++ = ' ', *p++ = ' ';
771
772         *p++ = ' ', *p++ = ' ', *p++ = ' ';
773
774         for( j = 0; j < i; j++ )
775         {
776             ch = pAddr[j];
777             *p++ = (ch > ' ' && ch < '~') ? ch : '.';
778         }
779
780         *p++ = '\0';
781         printk( "%s\r\n", szLine );
782
783         pAddr += i;
784     }
785     printk( "\r\n" );
786 } /* dumpaddr */
787
788
789 void kerSysMipsSoftReset(void)
790 {
791 #if defined(CONFIG_BCM96348)
792     if (PERF->RevID == 0x634800A1) {
793         typedef void (*FNPTR) (void);
794         FNPTR bootaddr = (FNPTR) FLASH_BASE;
795         int i;
796
797         /* Disable interrupts. */
798         cli();
799
800         /* Reset all blocks. */
801         PERF->BlockSoftReset &= ~BSR_ALL_BLOCKS;
802         for( i = 0; i < 1000000; i++ )
803             ;
804         PERF->BlockSoftReset |= BSR_ALL_BLOCKS;
805         /* Jump to the power on address. */
806         (*bootaddr) ();
807     }
808     else
809         PERF->pll_control |= SOFT_RESET;    // soft reset mips
810 #else
811     PERF->pll_control |= SOFT_RESET;    // soft reset mips
812 #endif
813 }
814
815
816 int kerSysGetMacAddress( unsigned char *pucaMacAddr, unsigned long ulId )
817 {
818     const unsigned long constMacAddrIncIndex = 3;
819     int nRet = 0;
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
825
826 //swda add,05/08/2006    
827 #ifdef BRCM_DRIVER_USB
828         ulWanBaseIdxId += 2;//ulWanBaseIdxId = 3
829 #endif
830 #ifdef WIRELESS
831 #ifndef BACKUP_WLAN_SPROM       //only wlan on board need mac assignment
832         ulWanBaseIdxId += 1;//ulWanBaseIdxId = 2 or 4
833 #endif
834 #endif
835 //swda add end
836
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);
841     baseMacAddr >>= 8;
842
843     for( i = 0, pMai = g_pNvramInfo->MacAddrs; i < g_pNvramInfo->ulNumMacAddrs;
844         i++, pMai++ )
845     {
846         if( ulId == pMai->ulId || ulId == MAC_ADDRESS_ANY )
847         {
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 );
854             pMai->chInUse = 1;
855             pMaiFreeNoId = pMaiFreeId = NULL;
856             break;
857         }
858         else
859             if( pMai->chInUse == 0 )
860             {
861                 if( pMai->ulId == 0 && pMaiFreeNoId == NULL )
862                 {
863                     /* This is an available MAC address that has never been
864                      * used.
865                      */
866                     pMaiFreeNoId = pMai;
867                     ulIdxNoId = i;
868                 }
869                 else
870                     if( pMai->ulId != 0 && pMaiFreeId == NULL )
871                     {
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.
875                          */
876                         pMaiFreeId = pMai;
877                         ulIdxId = i;
878                     }
879             }
880     }
881
882     if( pMaiFreeNoId || pMaiFreeId )
883     {
884         /* An available MAC address was found. */
885         memcpy(pucaMacAddr, g_pNvramInfo->ucaBaseMacAddr,NVRAM_MAC_ADDRESS_LEN);
886         if( pMaiFreeNoId )
887         {
888                 //swda modify,05/08/2006
889                 if ( ulIdxNoId >= ulWanBaseIdxId ) {
890                         pucaMacAddr[0] += (ulIdxNoId-ulWanBaseIdxId)*8+2;
891                 } else {
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 );
897             }
898             //swda modify end
899             pMaiFreeNoId->ulId = ulId;
900             pMaiFreeNoId->chInUse = 1;
901         }
902         else
903         {
904                 //swda modify,05/08/2006
905                 if ( ulIdxId >= ulWanBaseIdxId ) {
906                         pucaMacAddr[0] += (ulIdxId-ulWanBaseIdxId)*8+2;
907                 } else {
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 );
913             }
914             //swda modify end
915             pMaiFreeId->ulId = ulId;
916             pMaiFreeId->chInUse = 1;
917         }
918     }
919     else
920         if( i == g_pNvramInfo->ulNumMacAddrs )
921             nRet = -EADDRNOTAVAIL;
922
923     return( nRet );
924 } /* kerSysGetMacAddr */
925
926 int kerSysReleaseMacAddress( unsigned char *pucaMacAddr )
927 {
928     const unsigned long constMacAddrIncIndex = 3;
929     int nRet = -EINVAL;
930     unsigned long ulIdx = 0;
931     unsigned long baseMacAddr = 0;
932     unsigned long relMacAddr = 0;
933
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);
938     baseMacAddr >>= 8;
939
940     /* Get last 3 bytes of MAC address to release. */
941     memcpy((unsigned char *) &relMacAddr, &pucaMacAddr[constMacAddrIncIndex],
942         NVRAM_MAC_ADDRESS_LEN - constMacAddrIncIndex);
943     relMacAddr >>= 8;
944
945     ulIdx = relMacAddr - baseMacAddr;
946
947     if( ulIdx < g_pNvramInfo->ulNumMacAddrs )
948     {
949         PMAC_ADDR_INFO pMai = &g_pNvramInfo->MacAddrs[ulIdx];
950         if( pMai->chInUse == 1 )
951         {
952             pMai->chInUse = 0;
953             nRet = 0;
954         }
955     }
956
957     return( nRet );
958 } /* kerSysReleaseMacAddr */
959
960 int kerSysGetSdramSize( void )
961 {
962     return( (int) g_pNvramInfo->ulSdramSize );
963 } /* kerSysGetSdramSize */
964
965
966 void kerSysLedCtrl(BOARD_LED_NAME ledName, BOARD_LED_STATE ledState)
967 {
968     if (g_ledInitialized)
969       boardLedCtrl(ledName, ledState);
970 }
971
972 unsigned int kerSysMonitorPollHook( struct file *f, struct poll_table_struct *t)
973 {
974     int mask = (*g_orig_fop_poll) (f, t);
975
976     if( g_wakeup_monitor == 1 && g_monitor_file == f )
977     {
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.
981          */
982         mask |= POLLPRI;
983         g_wakeup_monitor = 0;
984     }
985
986     return( mask );
987 }
988
989 /* Put the user mode application that monitors link state on a run queue. */
990 void kerSysWakeupMonitorTask( void )
991 {
992     g_wakeup_monitor = 1;
993     if( g_monitor_task )
994         wake_up_process( g_monitor_task );
995 }
996 //#if defined(CONFIG_BCM96358) 
997 #if 0
998 static PFILE_TAG getTagFromPartition(int imageNumber)
999 {
1000     static unsigned char sectAddr1[sizeof(FILE_TAG)];
1001     static unsigned char sectAddr2[sizeof(FILE_TAG)];
1002     int blk = 0;
1003     UINT32 crc;
1004     PFILE_TAG pTag = NULL;
1005     unsigned char *pBase = flash_get_memptr(0);
1006     unsigned char *pSectAddr = NULL;
1007
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.
1011      */
1012     if( imageNumber == 1 )
1013     {
1014         blk = flash_get_blk((int) (pBase + FLASH_LENGTH_BOOT_ROM));
1015         pSectAddr = sectAddr1;
1016     }
1017     else
1018         if( imageNumber == 2 )
1019         {
1020             blk = flash_get_blk((int) (pBase + (flash_get_total_size() / 2)));
1021             pSectAddr = sectAddr2;
1022         }
1023
1024     if( blk )
1025     {
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)))
1032             pTag = NULL;
1033     }
1034
1035     return( pTag );
1036 }
1037
1038 static int getPartitionFromTag( PFILE_TAG pTag )
1039 {
1040     int ret = 0;
1041
1042     if( pTag )
1043     {
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)
1048             : -1;
1049         int sequence2 = (pTag2) ? simple_strtoul(pTag2->imageSequence, NULL, 10)
1050             : -1;
1051
1052         if( pTag1 && sequence == sequence1 )
1053             ret = 1;
1054         else
1055             if( pTag2 && sequence == sequence2 )
1056                 ret = 2;
1057     }
1058
1059     return( ret );
1060 }
1061
1062 static PFILE_TAG getBootImageTag(void)
1063 {
1064     PFILE_TAG pTag = NULL;
1065     PFILE_TAG pTag1 = getTagFromPartition(1);
1066     PFILE_TAG pTag2 = getTagFromPartition(2);
1067
1068     if( pTag1 && pTag2 )
1069     {
1070         /* Two images are flashed. */
1071         int sequence1 = simple_strtoul(pTag1->imageSequence, NULL, 10);
1072         int sequence2 = simple_strtoul(pTag2->imageSequence, NULL, 10);
1073         char *p;
1074         char bootPartition = BOOT_LATEST_IMAGE;
1075         NVRAM_DATA nvramData;
1076
1077         memcpy((char *) &nvramData, (char *) get_nvram_start_addr(),
1078             sizeof(nvramData));
1079         for( p = nvramData.szBootline; p[2] != '\0'; p++ )
1080             if( p[0] == 'p' && p[1] == '=' )
1081             {
1082                 bootPartition = p[2];
1083                 break;
1084             }
1085
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;
1090     }
1091     else
1092         /* One image is flashed. */
1093         pTag = (pTag2) ? pTag2 : pTag1;
1094
1095     return( pTag );
1096 }
1097
1098 static void UpdateImageSequenceNumber( unsigned char *imageSequence )
1099 {
1100     int newImageSequence = 0;
1101     PFILE_TAG pTag = getTagFromPartition(1);
1102
1103     if( pTag )
1104         newImageSequence = simple_strtoul(pTag->imageSequence, NULL, 10);
1105
1106     pTag = getTagFromPartition(2);
1107     if(pTag && simple_strtoul(pTag->imageSequence, NULL, 10) > newImageSequence)
1108         newImageSequence = simple_strtoul(pTag->imageSequence, NULL, 10);
1109
1110     newImageSequence++;
1111     sprintf(imageSequence, "%d", newImageSequence);
1112 }
1113
1114 static int flashFsKernelImage( int destAddr, unsigned char *imagePtr,
1115     int imageLen )
1116 {
1117     int status = 0;
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;
1121     char *p;
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;
1138
1139     memcpy((char *)&nvramData, (char *)get_nvram_start_addr(),sizeof(nvramData));
1140
1141     if( pCurTag )
1142     {
1143         curImgSize = simple_strtoul(pCurTag->rootfsLen, NULL, 10) +
1144             simple_strtoul(pCurTag->kernelLen, NULL, 10);
1145     }
1146
1147     if( newImgSize > availableSizeOneImg)
1148     {
1149         printk("Illegal image size %d.  Image size must not be greater "
1150             "than %d.\n", newImgSize, availableSizeOneImg);
1151         return -1;
1152     }
1153
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 )
1160     {
1161         // Update rootfsAddr to point to the second boot partition.
1162         int offset = (totalSize / 2) + TAG_LEN;
1163
1164         sprintf(((PFILE_TAG) tagFs)->kernelAddress, "%lu",
1165             (unsigned long) IMAGE_BASE + offset + (kernelAddr - rootfsAddr));
1166         kernelAddr = baseAddr + offset + (kernelAddr - rootfsAddr);
1167
1168         sprintf(((PFILE_TAG) tagFs)->rootfsAddress, "%lu",
1169             (unsigned long) IMAGE_BASE + offset);
1170         rootfsAddr = baseAddr + offset;
1171     }
1172
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;
1177
1178
1179     if( (status = kerSysBcmImageSet((rootfsAddr-TAG_LEN), tagFs,
1180         TAG_LEN + newImgSize)) != 0 )
1181     {
1182         printk("Failed to flash root file system. Error: %d\n", status);
1183         return status;
1184     }
1185
1186     for( p = nvramData.szBootline; p[2] != '\0'; p++ )
1187         if( p[0] == 'p' && p[1] == '=' && p[2] != BOOT_LATEST_IMAGE )
1188         {
1189             UINT32 crc = CRC32_INIT_VALUE;
1190     
1191             // Change boot partition to boot from new image.
1192             p[2] = BOOT_LATEST_IMAGE;
1193
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);
1198             break;
1199         }
1200
1201     return(status);
1202 }
1203 #else
1204 static PFILE_TAG getBootImageTag(void)
1205 {
1206     int i;
1207     int totalBlks = flash_get_numsectors();
1208     int totalSize = flash_get_total_size();
1209     int startblock,redo;
1210     UINT32 crc;
1211     unsigned char *sectAddr;
1212     unsigned char bootf1,bootf2,nbootflag=0;
1213
1214     PFILE_TAG pTag;
1215     int totalImageSize = 0;/* vic add to check image crc */
1216
1217 redo=1;
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 ) 
1223     {
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*/ 
1228         } 
1229         else nbootflag = 0; /* bank2 invalid bank1 valid */
1230     }
1231     else  if ((bootf2 >> 2) == 0 && bootf2) nbootflag =1; /*bank 1 invalid,bank 2 valid*/
1232     else  nbootflag=0; /* bank1 bank2 both invalid */
1233     
1234     //printf("bootf1 %x bootf2 %x\n", bootf1,bootf2);
1235 }
1236 else nbootflag=0; 
1237
1238 recheck:
1239
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);
1242
1243     // start from 2nd blk, assume 1st one is always CFE
1244     for (i = startblock; i < startblock + (totalBlks>>1) ; i++)
1245     {
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))) 
1251            return pTag;
1252     }
1253     return (PFILE_TAG) NULL;
1254
1255 }
1256 #endif
1257
1258 #if defined(CONFIG_BCM96358) 
1259 PFILE_TAG kerSysImageTagGet(void)
1260 {
1261     return( getBootImageTag() );
1262 }
1263 #endif
1264
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 )
1270 {
1271     int ret = 0;
1272     BOARD_IOCTL_PARMS ctrlParms;
1273     unsigned char ucaMacAddr[NVRAM_MAC_ADDRESS_LEN];
1274     
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*/
1278     int allowedSize;
1279     static unsigned char HasWriteBinfs=0;
1280 #endif
1281
1282     switch (command) 
1283     {
1284         case BOARD_IOCTL_FLASH_INIT:
1285             // not used for now.  kerSysBcmImageInit();
1286             break;
1287
1288         case BOARD_IOCTL_FLASH_WRITE:
1289             if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0)
1290             {
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];
1296 #endif
1297
1298                                 char Serial_No[SN_SIZE];
1299
1300 #ifdef  DEFAULT_WLAN_WEP128
1301                                 char WEP128bit_key[WEP128KEY_SIZE];
1302 #endif
1303 //swda add end
1304                 switch (ctrlParms.action)
1305                 {
1306     /*==== add by Andrew (2004/09/14)====*/
1307 #if defined(CFG_XFER_TO_FACDEFLT)
1308                                         case FACTDEFLT:
1309                                                 ret = kerSysFactDefltSet(ctrlParms.string, ctrlParms.strLen, ctrlParms.offset);
1310                                                 break;
1311 #endif
1312     /*==== end ====*/
1313
1314                     case SCRATCH_PAD:
1315                         if (ctrlParms.offset == -1)
1316                               ret =  kerSysScratchPadClearAll();
1317                         else
1318                               ret = kerSysScratchPadSet(ctrlParms.string, ctrlParms.buf, ctrlParms.offset);
1319                         break;
1320
1321                     case PERSISTENT:
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
1327                                                 //swda add end                                                             
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
1334                         } else {
1335                                 kerSysLedCtrl(kLedDiag, kLedStateOff);//red
1336                                 kerSysLedCtrl(kLedPower, kLedStateOn);//green
1337                         }
1338                                                 //swda add end
1339                         break;
1340                 
1341                     case NVRAM:
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));
1346                         }
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));      
1351                         }
1352                         else                            
1353                         ret = kerSysNvRamSet(ctrlParms.string, ctrlParms.strLen, ctrlParms.offset);
1354                         break;
1355 #if defined(CONFIG_BCM96348)                        
1356                     case BCM_IMAGE_BINFS:
1357                     
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);
1361                             ret = -1;
1362                             break;
1363                         }   
1364                      
1365                             
1366                         if( ctrlParms.strLen <= 0 || ctrlParms.strLen > 4*1024*1024 - 64*1024)
1367                         {
1368                             printk("Illegal root file system size [%d]. Size allowed: [%d]\n",
1369                                 ctrlParms.strLen,  allowedSize);
1370                             ret = -1;
1371                             break;
1372                         }
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
1382                         HasWriteBinfs = 1;
1383                         break;    
1384 #endif
1385
1386                     case BCM_IMAGE_CFE:
1387                         if( ctrlParms.strLen <= 0 || ctrlParms.strLen > FLASH_LENGTH_BOOT_ROM )
1388                         {
1389                             printk("Illegal CFE size [%d]. Size allowed: [%d]\n",
1390                                 ctrlParms.strLen, FLASH_LENGTH_BOOT_ROM);
1391                             ret = -1;
1392                             break;
1393                         }
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
1399 #endif
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);
1405 #endif       
1406                                         //save Serial Number into a local structure
1407                         kerSysNvRamGet(Serial_No, SN_SIZE, SN_OFFSET);
1408
1409 #ifdef  DEFAULT_WLAN_WEP128  //save WEP 128bit key into a local structure
1410                         kerSysNvRamGet(WEP128bit_key,WEP128KEY_SIZE,WEP128KEY_OFFSET);
1411 #endif
1412 //swda add end
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] );
1417
1418                         ret = kerSysBcmImageSet(ctrlParms.offset + BOOT_OFFSET, ctrlParms.string, ctrlParms.strLen);
1419
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 )
1423                         {
1424                             kerSysNvRamSet((char *) &SaveNvramData, sizeof(SaveNvramData), 0);
1425                         }
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);
1429
1430 #endif       
1431                                         //restore Serial Number
1432                         kerSysNvRamSet(Serial_No, SN_SIZE, SN_OFFSET);
1433
1434 #ifdef  DEFAULT_WLAN_WEP128 //restore WEP 128bit key
1435                         kerSysNvRamSet(WEP128bit_key,WEP128KEY_SIZE,WEP128KEY_OFFSET);
1436 #endif
1437 //swda add end 
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
1443 #endif                     
1444                         break;
1445                         
1446                     case BCM_IMAGE_FS:
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
1452
1453                         if( (ret = flashFsKernelImage( ctrlParms.offset,
1454                             ctrlParms.string, ctrlParms.strLen)) == 0 )
1455                         {
1456                             //swda: Power Led solid green
1457                             kerSysLedCtrl(kLedDiag, kLedStateOff);//red
1458                             kerSysLedCtrl(kLedPower, kLedStateOn);//green
1459                             kerSysSetUpgradeState(0); //upgrade end
1460
1461                             kerSysMipsSoftReset();
1462
1463                         }
1464 #else
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)
1468                         {
1469                             printk("Illegal root file system size [%d]. Size allowed: [%d]\n",
1470                                 ctrlParms.strLen,  allowedSize);
1471                             ret = -1;
1472                             break;
1473                         }
1474
1475                         //swda: Power Led flash red
1476                         kerSysLedCtrl(kLedPower, kLedStateOff);//green
1477                         kerSysLedCtrl(kLedDiag, kLedStateOn);//red
1478                         kerSysSetUpgradeState(1); //upgrade start
1479
1480                         //printk("\nflash fs offset at 0%x\n",ctrlParms.offset);
1481               
1482 #if defined(CONFIG_BCM96348)                        
1483                         {
1484                            unsigned char* bootflag;
1485                            PFILE_TAG pTag;
1486                            bootflag=flash_get_memptr((byte) 0);
1487                            int tagVer, curVer;
1488                            
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);
1493                            
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"); 
1497                               ret = -1;
1498                               break;
1499                            }                   
1500                                                      
1501                            if (totalSize == 0x800000) {nbootflag=*bootflag;printk("\nget bootflag %d\n",*bootflag);}
1502                            else nbootflag=1; 
1503                                                                        
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 */
1511                            }
1512                            
1513                            /*   nbootflag=1;  FAKE!!!! always flash bfc00000 */
1514
1515                            /* bootflag is 0 means boot from bfc00000 will flash bf800000 */
1516                            if (nbootflag==0) {                                  
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);
1526                               // get tag crc
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;
1532                                   nbootflag=1;
1533                            
1534                            }
1535                            else  nbootflag=0;  /* will flash bfc00000 if bootflag is 1(bf800000 is valid) or 2(binfs) or else */
1536                          
1537                         }
1538 #endif
1539
1540 #if defined(CONFIG_BCM96338) || defined(CONFIG_BCM96358)
1541         {
1542                 PFILE_TAG pTag;         
1543                 unsigned char bootf1,bootf2;
1544                 int tagVer, curVer;
1545                            
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);
1550                  
1551 #if defined(CONFIG_BCM96338)                     
1552                  if (totalSize == 0x400000) 
1553 #endif
1554 #if defined(CONFIG_BCM96358)
1555                                  if (totalSize == 0x800000) 
1556 #endif
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"); 
1559                        ret = -1;
1560                        break;
1561                    }  
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 */ 
1564 #endif
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 */ 
1567 #endif
1568
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(); }
1580                 
1581 #if defined(CONFIG_BCM96338)                     
1582                 if (totalSize == 0x400000)
1583 #endif
1584 #if defined(CONFIG_BCM96358)
1585                                 if (totalSize == 0x800000) 
1586 #endif
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 */
1590                     kerSysErasePS1();
1591                     nbootflag=2; /* skip set bootflag for bank 2 */
1592                 }                
1593                 
1594                 if (nbootflag==0) { /*boot from bank0 will flash bank1*/
1595
1596                         u_int32_t rootfs_addr,kernel_addr,tagCrc;
1597                                                                 
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);
1602                         
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) );
1606
1607                        sprintf(((PFILE_TAG) pTag)->rootfsAddress, "%lu",
1608                                (unsigned long) (rootfs_addr+(totalSize/2)-FLASH_LENGTH_BOOT_ROM));
1609             
1610                         // get tag crc
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 );
1616                         nbootflag=1;                                                                    
1617                 } else if ( nbootflag ==1 ) nbootflag=0;                                
1618         }
1619 #endif                       
1620                         ctrlParms.offset+= BOOT_OFFSET;
1621                         printk("Flashing@0%8x\n",ctrlParms.offset);                                                                                                                                                
1622                         ret = kerSysBcmImageSet(ctrlParms.offset, ctrlParms.string, ctrlParms.strLen);
1623
1624 #if defined(CONFIG_BCM96348)                         
1625                         if (totalSize == 0x800000)
1626                          if(HasWriteBinfs)  kerSysBootFlagSet(0x02);
1627                          else  kerSysBootFlagSet(nbootflag);
1628
1629 #endif
1630 #if defined(CONFIG_BCM96338)
1631                        if (totalSize == 0x400000 && (nbootflag<2) ) 
1632                            kerSysBootFlagSet(nbootflag);
1633
1634 #endif                    
1635 #if defined(CONFIG_BCM96358)
1636                        if (totalSize == 0x800000 && (nbootflag<2) ) 
1637                            kerSysBootFlagSet(nbootflag);
1638
1639 #endif  
1640                  
1641                         //swda: Power Led solid green
1642                         kerSysLedCtrl(kLedDiag, kLedStateOff);//red
1643                         kerSysLedCtrl(kLedPower, kLedStateOn);//green
1644                         kerSysSetUpgradeState(0); //upgrade end
1645                         kerSysMipsSoftReset();
1646 #endif
1647
1648                         break;
1649
1650                     case BCM_IMAGE_KERNEL:  // not used for now.
1651                         break;
1652                     case BCM_IMAGE_WHOLE:
1653                         if(ctrlParms.strLen <= 0)
1654                         {
1655                             printk("Illegal flash image size [%d].\n", ctrlParms.strLen);
1656                             ret = -1;
1657                             break;
1658                         }
1659
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
1665 #endif
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);
1671 #endif       
1672                                                 //save Serial Number into a local structure
1673                         kerSysNvRamGet(Serial_No, SN_SIZE, SN_OFFSET);
1674
1675 #ifdef  DEFAULT_WLAN_WEP128  //save WEP 128bit key into a local structure
1676                         kerSysNvRamGet(WEP128bit_key,WEP128KEY_SIZE,WEP128KEY_OFFSET);
1677 #endif
1678 //swda add end
1679                         if (ctrlParms.offset == 0) {
1680                             ctrlParms.offset = FLASH_BASE;
1681                         }
1682                         ret = kerSysBcmImageSet(ctrlParms.offset, ctrlParms.string, ctrlParms.strLen);
1683
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 )
1687                         {
1688                             kerSysNvRamSet((char *) &SaveNvramData, sizeof(SaveNvramData), 0);
1689                         }
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);
1693
1694 #endif       
1695                                                 //restore Serial Number
1696                         kerSysNvRamSet(Serial_No, SN_SIZE, SN_OFFSET);
1697
1698 #ifdef  DEFAULT_WLAN_WEP128 //restore WEP 128bit key
1699                         kerSysNvRamSet(WEP128bit_key,WEP128KEY_SIZE,WEP128KEY_OFFSET);
1700 #endif
1701 //swda add end
1702
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
1708 #endif                    
1709                         kerSysMipsSoftReset();
1710                         break;
1711
1712                     default:
1713                         ret = -EINVAL;
1714                         printk("flash_ioctl_command: invalid command %d\n", ctrlParms.action);
1715                         break;
1716                 }
1717                 ctrlParms.result = ret;
1718                 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
1719             }
1720             else
1721                 ret = -EFAULT;
1722             break;
1723
1724         case BOARD_IOCTL_FLASH_READ:
1725             if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) 
1726             {
1727                 switch (ctrlParms.action)
1728                 {
1729     /*==== add by Andrew (2004/09/14)====*/
1730 #if defined(CFG_XFER_TO_FACDEFLT)
1731                                         case FACTDEFLT:
1732                                                 ret = kerSysFactDefltGet(ctrlParms.string, ctrlParms.strLen, ctrlParms.offset);
1733                                                 break;
1734 #endif
1735     /*==== end ====*/
1736
1737                     case SCRATCH_PAD:
1738                         ret = kerSysScratchPadGet(ctrlParms.string, ctrlParms.buf, ctrlParms.offset);
1739                         break;
1740
1741                     case PERSISTENT:
1742                         ret = kerSysPersistentGet(ctrlParms.string, ctrlParms.strLen, ctrlParms.offset);
1743                         break;
1744
1745                     case NVRAM:
1746                         ret = kerSysNvRamGet(ctrlParms.string, ctrlParms.strLen, ctrlParms.offset);
1747                         break;
1748
1749                     case FLASH_SIZE:
1750                         ret = kerSysFlashSizeGet();
1751                         break;
1752
1753                     default:
1754                         ret = -EINVAL;
1755                         printk("Not supported.  invalid command %d\n", ctrlParms.action);
1756                         break;
1757                 }
1758                 ctrlParms.result = ret;
1759                 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
1760             }
1761             else
1762                 ret = -EFAULT;
1763             break;
1764
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));
1768             ret = 0;
1769             break;
1770
1771         case BOARD_IOCTL_DUMP_ADDR:
1772             if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) 
1773             {
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));
1777                 ret = 0;
1778             }
1779             else
1780                 ret = -EFAULT;
1781             break;
1782
1783         case BOARD_IOCTL_SET_MEMORY:
1784             if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) 
1785             {
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 )
1790                 {
1791                     case 4:
1792                         *pul = (unsigned long) ctrlParms.offset;
1793                         break;
1794                     case 2:
1795                         *pus = (unsigned short) ctrlParms.offset;
1796                         break;
1797                     case 1:
1798                         *puc = (unsigned char) ctrlParms.offset;
1799                         break;
1800                 }
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));
1804                 ret = 0;
1805             }
1806             else
1807                 ret = -EFAULT;
1808             break;
1809       
1810         case BOARD_IOCTL_MIPS_SOFT_RESET:
1811             kerSysMipsSoftReset();
1812             break;
1813
1814         case BOARD_IOCTL_LED_CTRL:
1815             if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) 
1816             {
1817                     kerSysLedCtrl((BOARD_LED_NAME)ctrlParms.strLen, (BOARD_LED_STATE)ctrlParms.offset);
1818                     ret = 0;
1819                 }
1820             break;
1821
1822         case BOARD_IOCTL_GET_ID:
1823             if (copy_from_user((void*)&ctrlParms, (void*)arg,
1824                 sizeof(ctrlParms)) == 0) 
1825             {
1826                 if( ctrlParms.string )
1827                 {
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);
1832                 }
1833
1834                 ctrlParms.result = 0;
1835                 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms,
1836                     sizeof(BOARD_IOCTL_PARMS));
1837             }
1838             break;
1839
1840         case BOARD_IOCTL_GET_MAC_ADDRESS:
1841             if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) 
1842             {
1843                 ctrlParms.result = kerSysGetMacAddress( ucaMacAddr,
1844                     ctrlParms.offset );
1845
1846                 if( ctrlParms.result == 0 )
1847                 {
1848                     __copy_to_user(ctrlParms.string, ucaMacAddr,
1849                         sizeof(ucaMacAddr));
1850                 }
1851
1852                 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms,
1853                     sizeof(BOARD_IOCTL_PARMS));
1854                 ret = 0;
1855             }
1856             else
1857                 ret = -EFAULT;
1858             break;
1859
1860         case BOARD_IOCTL_RELEASE_MAC_ADDRESS:
1861             if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) 
1862             {
1863                 if (copy_from_user((void*)ucaMacAddr, (void*)ctrlParms.string, \
1864                      NVRAM_MAC_ADDRESS_LEN) == 0) 
1865                 {
1866                     ctrlParms.result = kerSysReleaseMacAddress( ucaMacAddr );
1867                 }
1868                 else
1869                 {
1870                     ctrlParms.result = -EACCES;
1871                 }
1872
1873                 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms,
1874                     sizeof(BOARD_IOCTL_PARMS));
1875                 ret = 0;
1876             }
1877             else
1878                 ret = -EFAULT;
1879             break;
1880
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));
1884             ret = 0;
1885             break;
1886
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));
1890             ret = 0;
1891             break;
1892
1893         case BOARD_IOCTL_GET_BASE_MAC_ADDRESS:
1894             if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) 
1895             {
1896                 __copy_to_user(ctrlParms.string, g_pNvramInfo->ucaBaseMacAddr, NVRAM_MAC_ADDRESS_LEN);
1897                 ctrlParms.result = 0;
1898
1899                 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms,
1900                     sizeof(BOARD_IOCTL_PARMS));
1901                 ret = 0;
1902             }
1903             else
1904                 ret = -EFAULT;
1905             break;
1906
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));
1910             ret = 0;
1911             break;
1912
1913         case BOARD_IOCTL_GET_NUM_ENET: {
1914             ETHERNET_MAC_INFO EnetInfos[BP_MAX_ENET_MACS];
1915             int i, numeth = 0;
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) {
1919                 numeth++;
1920                 }
1921             }
1922             ctrlParms.result = numeth;
1923             __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms,  sizeof(BOARD_IOCTL_PARMS));   
1924             ret = 0;
1925             }
1926                 else {
1927                     ret = -EFAULT;
1928                 }
1929                 break;
1930             }
1931
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));
1938                     ret = -EFAULT;
1939                 }
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));
1943                     ret = 0;
1944                 }
1945                 else {
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));
1949                     ret = 0;
1950                 }
1951             }
1952             else {
1953                 ret = -EFAULT;
1954             }
1955             break;
1956
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));   
1965                         ret = 0;
1966                     } else
1967                             ret = -EFAULT;
1968                 }
1969                     else {
1970                         ret = -EFAULT;
1971                     }
1972                     break;
1973             }
1974             else {
1975                 ret = -EFAULT;
1976             }
1977             break;            
1978
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));   
1988                         ret = 0;
1989                     } else
1990                             ret = -EFAULT;
1991                 }
1992                 else {
1993                    ret = -EFAULT;
1994                 }
1995                 break;
1996             }
1997             else {
1998                 ret = -EFAULT;
1999             }
2000             break;            
2001 #endif            
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;
2006                 ret = -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;
2014                             ret = 0;
2015                         }                                                
2016                     } 
2017 #endif                                                
2018                     __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));                        
2019                 }
2020                 break;
2021             }
2022             else {
2023                 ret = -EFAULT;
2024             }
2025             break;                        
2026
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));   
2034                     ret = 0;
2035                 } else
2036                     ret = -EFAULT;
2037
2038                 break;
2039             }
2040             else {
2041                 ret = -EFAULT;
2042             }
2043             break;                
2044             
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));   
2052                     ret = 0;
2053                 } else
2054                     ret = -EFAULT;
2055
2056                 break;
2057             } 
2058             else {
2059                 ret = -EFAULT;
2060             }
2061             break;            
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));   
2069                     ret = 0;
2070                 } else
2071                     ret = -EFAULT;
2072
2073                 break;
2074             }
2075             else {
2076                 ret = -EFAULT;
2077             }
2078             break;            
2079 #endif                                                            
2080
2081         case BOARD_IOCTL_SET_MONITOR_FD:
2082             if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
2083                 int fput_needed = 0;
2084
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
2089                      * state.
2090                      */
2091                     g_monitor_task = current;
2092                     g_orig_fop_poll = g_monitor_file->f_op->poll;
2093                     g_monitor_file->f_op->poll = kerSysMonitorPollHook;
2094                 }
2095             }
2096             break;
2097
2098         case BOARD_IOCTL_WAKEUP_MONITOR_TASK:
2099             kerSysWakeupMonitorTask();
2100             break;
2101
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));
2106             }
2107             else {
2108                 ret = -EFAULT;  
2109                 ctrlParms.result = BP_NOT_DEFINED;
2110             }
2111
2112             break;
2113
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));
2118             } 
2119             else {
2120                 ret = -EFAULT;  
2121             }
2122             break;
2123
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));
2128                 ret = 0;
2129             } 
2130             else {
2131                 ret = -EFAULT;  
2132             }
2133             break;
2134
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));
2139                 ret = 0;
2140             } 
2141             else {
2142                 ret = -EFAULT;  
2143             }
2144             break;
2145
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));
2154                                 ret = 0;                        
2155                         } else {
2156                                 ret = -EFAULT;
2157                         }
2158                         break;          
2159
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));
2168                                 ret = 0;                        
2169                         } else {
2170                                 ret = -EFAULT;
2171                         }
2172                         break;
2173 #endif
2174
2175                 case BOARD_IOCTL_INFO_BOOT_COMPLETE:
2176                         printk("board_ioctl: boot complete!\n");
2177                         boot_complete_flag = 1;
2178                         break;
2179
2180 #ifdef  LLL_TEST_LED
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
2194                                 }
2195                                 ctrlParms.result = 0;
2196                                 ret = 0;                        
2197                         } else {
2198                                 ret = -EFAULT;
2199                         }
2200                         break;
2201 #endif
2202 #if VOXXXLOAD
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));
2208                         ret=0;
2209                         break;
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));
2215                         ret = 0;
2216                         break;
2217 #endif
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));
2222                         ret = 0;
2223                         break;
2224 #endif
2225
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;
2233                                 }
2234                                 
2235                                 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
2236                                 ret = 0;                        
2237                         } else {
2238                                 ret = -EFAULT;
2239                         }
2240                         break;
2241 #endif
2242 //swda add end    
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;
2248                                 }
2249                                 ctrlParms.result = 0;
2250                                 ret = 0;                        
2251                         } else {
2252                                 ret = -EFAULT;
2253                         }
2254                         break;
2255 //swda add end
2256         default:
2257             ret = -EINVAL;
2258             ctrlParms.result = 0;
2259             printk("board_ioctl: invalid command %x, cmd %d .\n",command,_IOC_NR(command));
2260             break;
2261
2262   } /* switch */
2263
2264   return (ret);
2265
2266 } /* board_ioctl */
2267
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)
2273 {   
2274     unsigned long gpio_mask = GPIO_NUM_TO_MASK(sesBtn_gpio);
2275     volatile unsigned long *gpio_io_reg = &GPIO->GPIOio;
2276
2277 #if !defined(CONFIG_BCM96338)
2278     if( (sesBtn_gpio & BP_GPIO_NUM_MASK) >= 32 )
2279     {
2280         gpio_mask = GPIO_NUM_TO_MASK_HIGH(sesBtn_gpio);
2281         gpio_io_reg = &GPIO->GPIOio_high;
2282     }
2283 #endif 
2284                 
2285     if (!(*gpio_io_reg & gpio_mask)){
2286         wake_up_interruptible(&g_board_wait_queue);
2287         return IRQ_RETVAL(1);
2288     } else {
2289         return IRQ_RETVAL(0);           
2290     }
2291 }
2292
2293 static void __init sesBtn_mapGpio()
2294 {       
2295     if( BpGetWirelessSesBtnGpio(&sesBtn_gpio) == BP_SUCCESS )
2296     {
2297         printk("SES: Button GPIO 0x%x is enabled\n", sesBtn_gpio);    
2298     }
2299 }
2300
2301 static void __init sesBtn_mapIntr(int context)
2302 {       
2303     if( BpGetWirelessSesExtIntr(&sesBtn_irq) == BP_SUCCESS )
2304     {
2305         printk("SES: Button Interrupt 0x%x is enabled\n", sesBtn_irq);
2306     }
2307     else
2308         return;
2309             
2310     sesBtn_irq += INTERRUPT_ID_EXTERNAL_0;      
2311                 
2312     if (BcmHalMapInterrupt((FN_HANDLER)sesBtn_isr, context, sesBtn_irq)) {
2313         printk("SES: Interrupt mapping failed\n");
2314     }    
2315     BcmHalInterruptEnable(sesBtn_irq);
2316 }
2317
2318
2319 static unsigned int sesBtn_poll(struct file *file, struct poll_table_struct *wait)
2320 {
2321     unsigned long gpio_mask = GPIO_NUM_TO_MASK(sesBtn_gpio);
2322     volatile unsigned long *gpio_io_reg = &GPIO->GPIOio;
2323
2324 #if !defined(CONFIG_BCM96338)
2325     if( (sesBtn_gpio & BP_GPIO_NUM_MASK) >= 32 )
2326     {
2327         gpio_mask = GPIO_NUM_TO_MASK_HIGH(sesBtn_gpio);
2328         gpio_io_reg = &GPIO->GPIOio_high;
2329     }
2330 #endif 
2331                 
2332     if (!(*gpio_io_reg & gpio_mask)){
2333         return POLLIN;
2334     }   
2335     return 0;
2336 }
2337
2338 static ssize_t sesBtn_read(struct file *file,  char __user *buffer, size_t count, loff_t *ppos)
2339 {
2340     volatile unsigned int event=0;
2341     ssize_t ret=0;      
2342
2343     unsigned long gpio_mask = GPIO_NUM_TO_MASK(sesBtn_gpio);
2344     volatile unsigned long *gpio_io_reg = &GPIO->GPIOio;
2345     
2346 #if !defined (CONFIG_BCM96338)
2347     if( (sesBtn_gpio & BP_GPIO_NUM_MASK) >= 32 )
2348     {
2349         gpio_mask = GPIO_NUM_TO_MASK_HIGH(sesBtn_gpio);
2350         gpio_io_reg = &GPIO->GPIOio_high;
2351     }
2352 #endif 
2353
2354     if(*gpio_io_reg & gpio_mask){
2355         BcmHalInterruptEnable(sesBtn_irq);              
2356             return ret;
2357     }   
2358     event = SES_EVENTS;
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);       
2364     return ret; 
2365 }
2366
2367 static void __init sesLed_mapGpio()
2368 {       
2369     if( BpGetWirelessSesBtnGpio(&sesLed_gpio) == BP_SUCCESS )
2370     {
2371         printk("SES: LED GPIO 0x%x is enabled\n", sesBtn_gpio);    
2372     }
2373 }
2374
2375 static void sesLed_ctrl(int action)
2376 {
2377
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  */
2381     
2382     BOARD_LED_STATE led;
2383     
2384     if(sesLed_gpio == BP_NOT_DEFINED)
2385         return;
2386         
2387     action &= 0xff; /* extract led */
2388
2389     //printk("blinktype=%d, event=%d, status=%d\n",(int)blinktype, (int)event, (int)status);
2390                 
2391     switch (action) 
2392     {
2393         case SES_LED_ON:
2394             //printk("SES: led on\n");
2395             led = kLedStateOn;                                          
2396             break;
2397         case SES_LED_BLINK:
2398             //printk("SES: led blink\n");
2399             led = kLedStateSlowBlinkContinues;                          
2400             break;
2401         case SES_LED_OFF:
2402             default:
2403             //printk("SES: led off\n");
2404             led = kLedStateOff;                                                 
2405     }   
2406     
2407     kerSysLedCtrl(kLedSes, led);
2408 }
2409
2410 static void __init ses_board_init()
2411 {
2412     sesBtn_mapGpio();
2413     sesBtn_mapIntr(0);
2414     sesLed_mapGpio();
2415 }
2416 static void __exit ses_board_deinit()
2417 {
2418     if(sesBtn_irq)
2419         BcmHalInterruptDisable(sesBtn_irq);
2420 }
2421 #endif
2422
2423 /***************************************************************************
2424  * Dying gasp ISR and functions.
2425  ***************************************************************************/
2426 #define KERSYS_DBG      printk
2427
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.
2432  */
2433 #define CYCLE_PER_US    120
2434 #elif defined(CONFIG_BCM96358)
2435 #define CYCLE_PER_US    150
2436 #endif
2437 #define DG_GLITCH_TO    (100*CYCLE_PER_US)
2438  
2439 static void __init kerSysDyingGaspMapIntr()
2440 {
2441     unsigned long ulIntr;
2442         
2443     if( BpGetAdslDyingGaspExtIntr( &ulIntr ) == BP_SUCCESS ) {
2444                 BcmHalMapInterrupt((FN_HANDLER)kerSysDyingGaspIsr, 0, INTERRUPT_ID_DG);
2445                 BcmHalInterruptEnable( INTERRUPT_ID_DG );
2446     }
2447
2448
2449 void kerSysSetWdTimer(ulong timeUs)
2450 {
2451         TIMER->WatchDogDefCount = timeUs * (FPERIPH/1000000);
2452         TIMER->WatchDogCtl = 0xFF00;
2453         TIMER->WatchDogCtl = 0x00FF;
2454 }
2455
2456 ulong kerSysGetCycleCount(void)
2457 {
2458     ulong cnt; 
2459 #ifdef _WIN32_WCE
2460     cnt = 0;
2461 #else
2462     __asm volatile("mfc0 %0, $9":"=d"(cnt));
2463 #endif
2464     return(cnt); 
2465 }
2466
2467 static Bool kerSysDyingGaspCheckPowerLoss(void)
2468 {
2469     ulong clk0;
2470     ulong ulIntr;
2471
2472     ulIntr = 0;
2473     clk0 = kerSysGetCycleCount();
2474
2475     UART->Data = 'D';
2476     UART->Data = '%';
2477     UART->Data = 'G';
2478
2479     do {
2480         ulong clk1;
2481         
2482         clk1 = kerSysGetCycleCount();           /* time cleared */
2483         /* wait a little to get new reading */
2484         while ((kerSysGetCycleCount()-clk1) < CYCLE_PER_US*2)
2485             ;
2486      } while ((PERF->IrqStatus & (1 << (INTERRUPT_ID_DG - INTERNAL_ISR_TABLE_OFFSET))) && ((kerSysGetCycleCount() - clk0) < DG_GLITCH_TO));
2487
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);
2491         return 0;
2492     }
2493
2494     return 1;
2495 }
2496
2497 static void kerSysDyingGaspShutdown( void )
2498 {
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);
2504 #endif
2505 }
2506
2507 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
2508 static irqreturn_t kerSysDyingGaspIsr(int irq, void * dev_id, struct pt_regs * regs)
2509 #else
2510 static unsigned int kerSysDyingGaspIsr(void)
2511 #endif
2512 {       
2513     struct list_head *pos;
2514     CB_DGASP_LIST *tmp = NULL, *dsl = NULL;     
2515
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);
2524 #endif
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); 
2531 #else
2532                 ;
2533 #endif
2534             }else {
2535                 dsl = tmp;                      
2536             }       
2537         }  
2538         
2539         /* now send dgasp */
2540         if(dsl)
2541             (dsl->cb_dgasp_fn)(dsl->context); 
2542 #if POWER_SAVING_DG     //swda mark,06/15/2006
2543         /* reset and shutdown system */
2544         kerSysDyingGaspShutdown();
2545
2546         // If power is going down, nothing should continue!
2547
2548         while (1)
2549             ;
2550 #endif
2551     }
2552 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
2553 return( IRQ_HANDLED );
2554 #else
2555     return( 1 );
2556 #endif
2557 }
2558
2559 static void __init kerSysInitDyingGaspHandler( void )
2560 {
2561     CB_DGASP_LIST *new_node;
2562
2563     if( g_cb_dgasp_list_head != NULL) {
2564         printk("Error: kerSysInitDyingGaspHandler: list head is not null\n");
2565         return; 
2566     }
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; 
2571                 
2572 } /* kerSysInitDyingGaspHandler */
2573
2574 static void __exit kerSysDeinitDyingGaspHandler( void )
2575 {
2576     struct list_head *pos;
2577     CB_DGASP_LIST *tmp; 
2578         
2579     if(g_cb_dgasp_list_head == NULL)
2580         return;
2581         
2582     list_for_each(pos, &g_cb_dgasp_list_head->list) {           
2583         tmp = list_entry(pos, CB_DGASP_LIST, list);
2584         list_del(pos);
2585         kfree(tmp);
2586     }       
2587
2588     kfree(g_cb_dgasp_list_head);        
2589     g_cb_dgasp_list_head = NULL;
2590     
2591 } /* kerSysDeinitDyingGaspHandler */
2592
2593 void kerSysRegisterDyingGaspHandler(char *devname, void *cbfn, void *context)
2594 {
2595     CB_DGASP_LIST *new_node;
2596
2597     if( g_cb_dgasp_list_head == NULL) {
2598         printk("Error: kerSysRegisterDyingGaspHandler: list head is null\n");   
2599         return;    
2600     }
2601     
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);             
2604         return;
2605     }
2606        
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);
2614     
2615     printk("dgasp: kerSysRegisterDyingGaspHandler: %s registered \n", devname);
2616                 
2617 } /* kerSysRegisterDyingGaspHandler */
2618
2619 void kerSysDeregisterDyingGaspHandler(char *devname)
2620 {
2621     struct list_head *pos;
2622     CB_DGASP_LIST *tmp;    
2623     
2624     if(g_cb_dgasp_list_head == NULL) {
2625         printk("Error: kerSysDeregisterDyingGaspHandler: list head is null\n");
2626         return; 
2627     }
2628
2629     if(devname == NULL) {
2630         printk("Error: kerSysDeregisterDyingGaspHandler: devname is null\n");
2631         return; 
2632     }
2633     
2634     printk("kerSysDeregisterDyingGaspHandler: %s is deregistering\n", devname);
2635
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)) {
2639             list_del(pos);
2640             kfree(tmp);
2641             printk("kerSysDeregisterDyingGaspHandler: %s is deregistered\n", devname);
2642             return;
2643         }
2644     }   
2645     printk("kerSysDeregisterDyingGaspHandler: %s not (de)registered\n", devname);
2646         
2647 } /* kerSysDeregisterDyingGaspHandler */
2648
2649 static int ConfigCs (BOARD_IOCTL_PARMS *parms)
2650 {
2651     int                     retv = 0;
2652 #if !defined(CONFIG_BCM96338)
2653     int                     cs, flags;
2654     cs_config_pars_t        info;
2655
2656     if (copy_from_user(&info, (void*)parms->buf, sizeof(cs_config_pars_t)) == 0) 
2657     {
2658         cs = parms->offset;
2659
2660         MPI->cs[cs].base = ((info.base & 0x1FFFE000) | (info.size >> 13));      
2661
2662         if ( info.mode == EBI_TS_TA_MODE )     // syncronious mode
2663             flags = (EBI_TS_TA_MODE | EBI_ENABLE);
2664         else
2665         {
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 )) );
2670         }
2671         MPI->cs[cs].config = flags;
2672         parms->result = BP_SUCCESS;
2673         retv = 0;
2674     }
2675     else
2676     {
2677         retv -= EFAULT;
2678         parms->result = BP_NOT_DEFINED; 
2679     }
2680 #endif
2681     return( retv );
2682 }
2683
2684 static void SetPll (int pll_mask, int pll_value)
2685 {
2686     PERF->pll_control &= ~pll_mask;   // clear relevant bits
2687     PERF->pll_control |= pll_value;   // and set desired value
2688 }
2689
2690 static void SetGpio(int gpio, GPIO_STATE_t state)
2691 {
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;
2695     
2696 #if !defined (CONFIG_BCM96338)
2697     if( gpio >= 32 )
2698     {
2699         gpio_mask = GPIO_NUM_TO_MASK_HIGH(gpio);
2700         gpio_io_reg = &GPIO->GPIOio_high;
2701         gpio_dir_reg = &GPIO->GPIODir_high;
2702     }
2703 #endif 
2704
2705     *gpio_dir_reg |= gpio_mask;
2706
2707     if(state == GPIO_HIGH)
2708         *gpio_io_reg |= gpio_mask;
2709     else
2710         *gpio_io_reg &= ~gpio_mask;
2711 }
2712
2713
2714 static irqreturn_t reset_isr(int irq, void *dev_id, struct pt_regs *ptregs)
2715 {
2716     printk("\n*** Restore to Factory Default Setting ***\n\n");
2717     kerSysPersistentSet( "Reset Persistent", strlen("Reset Persistent"), 0 );
2718     kerSysMipsSoftReset();
2719     return 0;
2720 }
2721
2722
2723 //swda add,05/10/2006
2724 #ifdef BACKUP_WLAN_SPROM
2725 void kerSysGetSpromSavedFlag(unsigned char *pspromsavedflag)
2726 {
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;
2731 }
2732 void kerSysSetSpromSavedFlag(unsigned char spromsavedflag)
2733 {
2734          PNVRAM_DATA pNvramData = (PNVRAM_DATA) get_nvram_start_addr();
2735          NVRAM_DATA SaveNvramData;
2736          UINT32 crc = CRC32_INIT_VALUE;
2737     
2738          // save NVRAM data into a local structure
2739      memcpy( &SaveNvramData, pNvramData, sizeof(NVRAM_DATA) );
2740      SaveNvramData.sprom_saved_flag = spromsavedflag;
2741      
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);
2747 }
2748 void kerSysGetSpromTable(char *pspromdata,int size,int offset)
2749 {
2750      //kerSysNvRamGet(pspromdata, size, offset);
2751      //SPROM has been read in InitNvramInfo
2752      memcpy(pspromdata,g_SPROMData,NVRAM_SPROM_TABLE_SIZE);
2753 }
2754 void kerSysSetSpromTable(char *pspromdata,int size,int offset)
2755 {
2756      kerSysNvRamSet(pspromdata, size, offset);
2757 }
2758 #endif //BACKUP_WLAN_SPROM
2759
2760 int kerSysSetUpgradeState(int state)
2761 {
2762         is_update_flash = state;
2763 }
2764 int kerSysGetUpgradeState(void)
2765 {
2766         return is_update_flash;
2767 }
2768 //swda add end
2769
2770 /***************************************************************************
2771  * MACRO to call driver initialization and cleanup functions.
2772  ***************************************************************************/
2773 module_init( brcm_board_init );
2774 module_exit( brcm_board_cleanup );
2775
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);
2820 #endif
2821 EXPORT_SYMBOL(kerSysGetUpgradeState);//swda add,06/27/2006