3 Copyright 2002 Broadcom Corp. All Rights Reserved.
5 This program is free software; you can distribute it and/or modify it
6 under the terms of the GNU General Public License (Version 2) as
7 published by the Free Software Foundation.
9 This program is distributed in the hope it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
19 /***************************************************************************
22 * Description: This file contains Linux character device driver entry
23 * for the board related ioctl calls: flash, get free kernel
24 * page and dump kernel memory, etc.
26 * Created on : 2/20/2002 seanl: use cfiflash.c, cfliflash.h (AMD specific)
28 ***************************************************************************/
32 #include <linux/init.h>
34 #include <linux/interrupt.h>
35 #include <linux/capability.h>
36 #include <linux/slab.h>
37 #include <linux/errno.h>
38 #include <linux/module.h>
39 #include <linux/pagemap.h>
40 #include <asm/uaccess.h>
42 #include <bcm_map_part.h>
45 #include "boardparms.h"
49 #if defined (NON_CONSECUTIVE_MAC)
50 // used to be the last octet. Now changed to the first 5 bits of the the forth octet
51 // to reduced the duplicated MAC addresses.
52 #define CHANGED_OCTET 3
55 #define CHANGED_OCTET 1
64 } MAC_ADDR_INFO, *PMAC_ADDR_INFO;
68 unsigned long ulSdramSize;
69 unsigned long ulPsiSize;
70 unsigned long ulNumMacAddrs;
71 unsigned long ucaBaseMacAddr[NVRAM_MAC_ADDRESS_LEN];
72 MAC_ADDR_INFO MacAddrs[1];
73 } NVRAM_INFO, *PNVRAM_INFO;
76 static LED_MAP_PAIR LedMapping[] =
77 { // led name Initial state physical pin (ledMask)
78 {kLedEnd, kLedStateOff, 0, 0, 0, 0},
79 {kLedEnd, kLedStateOff, 0, 0, 0, 0},
80 {kLedEnd, kLedStateOff, 0, 0, 0, 0},
81 {kLedEnd, kLedStateOff, 0, 0, 0, 0},
82 {kLedEnd, kLedStateOff, 0, 0, 0, 0},
83 {kLedEnd, kLedStateOff, 0, 0, 0, 0},
84 {kLedEnd, kLedStateOff, 0, 0, 0, 0},
85 {kLedEnd, kLedStateOff, 0, 0, 0, 0} // NOTE: kLedEnd has to be at the end.
89 extern unsigned int nr_free_pages (void);
90 extern const char *get_system_type(void);
91 extern void kerSysFlashInit(void);
92 extern unsigned long get_nvram_start_addr(void);
93 extern unsigned long get_scratch_pad_start_addr(void);
94 extern unsigned long getMemorySize(void);
95 extern void __init boardLedInit(PLED_MAP_PAIR);
96 extern void boardLedCtrl(BOARD_LED_NAME, BOARD_LED_STATE);
97 extern void kerSysLedRegisterHandler( BOARD_LED_NAME ledName,
98 HANDLE_LED_FUNC ledHwFunc, int ledFailType );
101 void __init InitNvramInfo( void );
102 static int board_open( struct inode *inode, struct file *filp );
103 static int board_ioctl( struct inode *inode, struct file *flip,
104 unsigned int command, unsigned long arg );
106 static PNVRAM_INFO g_pNvramInfo = NULL;
107 static int g_ledInitialized = 0;
109 static struct file_operations board_fops =
115 uint32 board_major = 0;
119 int init_module(void)
121 return( brcm_board_init() );
124 void cleanup_module(void)
127 printk("brcm flash: cleanup_module failed because module is in use\n");
129 brcm_board_cleanup();
135 static int __init brcm_board_init( void )
137 typedef int (*BP_LED_FUNC) (unsigned short *);
138 static struct BpLedInformation
140 BOARD_LED_NAME ledName;
142 BP_LED_FUNC bpFuncFail;
144 {{kLedAdsl, BpGetAdslLedGpio, BpGetAdslFailLedGpio},
145 {kLedWireless, BpGetWirelessLedGpio, NULL},
146 {kLedUsb, BpGetUsbLedGpio, NULL},
147 {kLedHpna, BpGetHpnaLedGpio, NULL},
148 {kLedWanData, BpGetWanDataLedGpio, NULL},
149 {kLedPPP, BpGetPppLedGpio, BpGetPppFailLedGpio},
150 {kLedVoip, BpGetVoipLedGpio, NULL},
151 {kLedEnd, NULL, NULL}
156 ret = register_chrdev(BOARD_DRV_MAJOR, "bcrmboard", &board_fops );
158 printk( "brcm_board_init(major %d): fail to register device.\n",BOARD_DRV_MAJOR);
161 PLED_MAP_PAIR pLedMap = LedMapping;
163 struct BpLedInformation *pInfo;
165 printk("brcmboard: brcm_board_init entry\n");
166 board_major = BOARD_DRV_MAJOR;
169 for( pInfo = bpLedInfo; pInfo->ledName != kLedEnd; pInfo++ )
171 if( pInfo->bpFunc && (*pInfo->bpFunc) (&gpio) == BP_SUCCESS )
173 pLedMap->ledName = pInfo->ledName;
174 pLedMap->ledMask = GPIO_NUM_TO_MASK(gpio);
175 pLedMap->ledActiveLow = (gpio & BP_ACTIVE_LOW) ? 1 : 0;
177 if( pInfo->bpFuncFail && (*pInfo->bpFuncFail) (&gpio) == BP_SUCCESS )
179 pLedMap->ledName = pInfo->ledName;
180 pLedMap->ledMaskFail = GPIO_NUM_TO_MASK(gpio);
181 pLedMap->ledActiveLowFail = (gpio & BP_ACTIVE_LOW) ? 1 : 0;
183 if( pLedMap->ledName != kLedEnd )
187 boardLedInit(LedMapping);
188 g_ledInitialized = 1;
194 void __init InitNvramInfo( void )
196 PNVRAM_DATA pNvramData = (PNVRAM_DATA) get_nvram_start_addr();
197 unsigned long ulNumMacAddrs = pNvramData->ulNumMacAddrs;
199 if( ulNumMacAddrs > 0 && ulNumMacAddrs <= NVRAM_MAC_COUNT_MAX )
201 unsigned long ulNvramInfoSize =
202 sizeof(NVRAM_INFO) + ((sizeof(MAC_ADDR_INFO) - 1) * ulNumMacAddrs);
204 g_pNvramInfo = (PNVRAM_INFO) kmalloc( ulNvramInfoSize, GFP_KERNEL );
208 unsigned long ulPsiSize;
209 if( BpGetPsiSize( &ulPsiSize ) != BP_SUCCESS )
210 ulPsiSize = NVRAM_PSI_DEFAULT;
211 memset( g_pNvramInfo, 0x00, ulNvramInfoSize );
212 g_pNvramInfo->ulPsiSize = ulPsiSize * 1024;
213 g_pNvramInfo->ulNumMacAddrs = pNvramData->ulNumMacAddrs;
214 memcpy( g_pNvramInfo->ucaBaseMacAddr, pNvramData->ucaBaseMacAddr,
215 NVRAM_MAC_ADDRESS_LEN );
216 g_pNvramInfo->ulSdramSize = getMemorySize();
219 printk("ERROR - Could not allocate memory for NVRAM data\n");
222 printk("ERROR - Invalid number of MAC addresses (%ld) is configured.\n",
226 void __exit brcm_board_cleanup( void )
228 printk("brcm_board_cleanup()\n");
230 if (board_major != -1)
232 unregister_chrdev(board_major, "board_ioctl");
236 static int board_open( struct inode *inode, struct file *filp )
242 //**************************************************************************************
243 // Utitlities for dump memory, free kernel pages, mips soft reset, etc.
244 //**************************************************************************************
246 /***********************************************************************
247 * Function Name: dumpaddr
248 * Description : Display a hex dump of the specified address.
249 ***********************************************************************/
250 void dumpaddr( unsigned char *pAddr, int nLen )
252 static char szHexChars[] = "0123456789abcdef";
255 unsigned char ch, *q;
261 sprintf( szLine, "%8.8lx: ", (unsigned long) pAddr );
262 p = szLine + strlen(szLine);
264 for(i = 0; i < 16 && nLen > 0; i += sizeof(long), nLen -= sizeof(long))
266 ul = *(unsigned long *) &pAddr[i];
267 q = (unsigned char *) &ul;
268 for( j = 0; j < sizeof(long); j++ )
270 *p++ = szHexChars[q[j] >> 4];
271 *p++ = szHexChars[q[j] & 0x0f];
276 for( j = 0; j < 16 - i; j++ )
277 *p++ = ' ', *p++ = ' ', *p++ = ' ';
279 *p++ = ' ', *p++ = ' ', *p++ = ' ';
281 for( j = 0; j < i; j++ )
284 *p++ = (ch > ' ' && ch < '~') ? ch : '.';
288 printk( "%s\r\n", szLine );
296 void kerSysMipsSoftReset(void)
298 #if defined(CONFIG_BCM96348)
299 if (PERF->RevID == 0x634800A1) {
300 typedef void (*FNPTR) (void);
301 FNPTR bootaddr = (FNPTR) FLASH_BASE;
304 /* Disable interrupts. */
307 /* Reset all blocks. */
308 PERF->BlockSoftReset &= ~BSR_ALL_BLOCKS;
309 for( i = 0; i < 1000000; i++ )
311 PERF->BlockSoftReset |= BSR_ALL_BLOCKS;
312 /* Jump to the power on address. */
316 PERF->pll_control |= SOFT_RESET; // soft reset mips
318 PERF->pll_control |= SOFT_RESET; // soft reset mips
323 int kerSysGetMacAddress( unsigned char *pucaMacAddr, unsigned long ulId )
326 PMAC_ADDR_INFO pMai = NULL;
327 PMAC_ADDR_INFO pMaiFreeNoId = NULL;
328 PMAC_ADDR_INFO pMaiFreeId = NULL;
329 unsigned long i = 0, ulIdxNoId = 0, ulIdxId = 0, shiftedIdx = 0;
331 for( i = 0, pMai = g_pNvramInfo->MacAddrs; i < g_pNvramInfo->ulNumMacAddrs;
334 if( ulId == pMai->ulId || ulId == MAC_ADDRESS_ANY )
336 /* This MAC address has been used by the caller in the past. */
337 memcpy( pucaMacAddr, g_pNvramInfo->ucaBaseMacAddr,
338 NVRAM_MAC_ADDRESS_LEN );
340 pucaMacAddr[NVRAM_MAC_ADDRESS_LEN - CHANGED_OCTET] += (shiftedIdx << SHIFT_BITS);
342 pMaiFreeNoId = pMaiFreeId = NULL;
346 if( pMai->chInUse == 0 )
348 if( pMai->ulId == 0 && pMaiFreeNoId == NULL )
350 /* This is an available MAC address that has never been
357 if( pMai->ulId != 0 && pMaiFreeId == NULL )
359 /* This is an available MAC address that has been used
360 * before. Use addresses that have never been used
361 * first, before using this one.
369 if( pMaiFreeNoId || pMaiFreeId )
371 /* An available MAC address was found. */
372 memcpy(pucaMacAddr, g_pNvramInfo->ucaBaseMacAddr,NVRAM_MAC_ADDRESS_LEN);
375 shiftedIdx = ulIdxNoId;
376 pucaMacAddr[NVRAM_MAC_ADDRESS_LEN - CHANGED_OCTET] += (shiftedIdx << SHIFT_BITS);
377 pMaiFreeNoId->ulId = ulId;
378 pMaiFreeNoId->chInUse = 1;
382 shiftedIdx = ulIdxId;
383 pucaMacAddr[NVRAM_MAC_ADDRESS_LEN - CHANGED_OCTET] += (shiftedIdx << SHIFT_BITS);
384 pMaiFreeId->ulId = ulId;
385 pMaiFreeId->chInUse = 1;
389 if( i == g_pNvramInfo->ulNumMacAddrs )
390 nRet = -EADDRNOTAVAIL;
393 } /* kerSysGetMacAddr */
395 int kerSysReleaseMacAddress( unsigned char *pucaMacAddr )
398 unsigned long ulIdx = 0;
399 int idx = (pucaMacAddr[NVRAM_MAC_ADDRESS_LEN - CHANGED_OCTET] -
400 g_pNvramInfo->ucaBaseMacAddr[NVRAM_MAC_ADDRESS_LEN - CHANGED_OCTET]);
402 // if overflow 255 (negitive), add 256 to have the correct index
405 ulIdx = (unsigned long) (idx >> SHIFT_BITS);
407 if( ulIdx < g_pNvramInfo->ulNumMacAddrs )
409 PMAC_ADDR_INFO pMai = &g_pNvramInfo->MacAddrs[ulIdx];
410 if( pMai->chInUse == 1 )
418 } /* kerSysReleaseMacAddr */
420 int kerSysGetSdramSize( void )
422 return( (int) g_pNvramInfo->ulSdramSize );
423 } /* kerSysGetSdramSize */
426 void kerSysLedCtrl(BOARD_LED_NAME ledName, BOARD_LED_STATE ledState)
428 if (g_ledInitialized)
429 boardLedCtrl(ledName, ledState);
433 //********************************************************************************************
434 // misc. ioctl calls come to here. (flash, led, reset, kernel memory access, etc.)
435 //********************************************************************************************
436 static int board_ioctl( struct inode *inode, struct file *flip,
437 unsigned int command, unsigned long arg )
440 BOARD_IOCTL_PARMS ctrlParms;
441 unsigned char ucaMacAddr[NVRAM_MAC_ADDRESS_LEN];
446 case BOARD_IOCTL_FLASH_INIT:
447 // not used for now. kerSysBcmImageInit();
451 case BOARD_IOCTL_FLASH_WRITE:
452 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0)
454 NVRAM_DATA SaveNvramData;
455 PNVRAM_DATA pNvramData = (PNVRAM_DATA) get_nvram_start_addr();
457 switch (ctrlParms.action)
460 ret = kerSysScratchPadSet(ctrlParms.string, ctrlParms.buf, ctrlParms.offset);
464 ret = kerSysPersistentSet(ctrlParms.string, ctrlParms.strLen, ctrlParms.offset);
468 ret = kerSysNvRamSet(ctrlParms.string, ctrlParms.strLen, ctrlParms.offset);
472 if( ctrlParms.strLen <= 0 || ctrlParms.strLen > FLASH45_LENGTH_BOOT_ROM )
474 printk("Illegal CFE size [%d]. Size allowed: [%d]\n",
475 ctrlParms.strLen, FLASH45_LENGTH_BOOT_ROM);
480 // save NVRAM data into a local structure
481 memcpy( &SaveNvramData, pNvramData, sizeof(NVRAM_DATA) );
483 // set memory type field
484 BpGetSdramSize( (unsigned long *) &ctrlParms.string[SDRAM_TYPE_ADDRESS_OFFSET] );
486 ret = kerSysBcmImageSet(ctrlParms.offset, ctrlParms.string, ctrlParms.strLen);
488 // if nvram is not valid, restore the current nvram settings
489 if( BpSetBoardId( pNvramData->szBoardId ) != BP_SUCCESS &&
490 *(unsigned long *) pNvramData == NVRAM_DATA_ID )
492 kerSysNvRamSet((char *) &SaveNvramData, sizeof(SaveNvramData), 0);
497 allowedSize = (int) flash_get_total_size() - \
498 FLASH_RESERVED_AT_END - TAG_LEN - FLASH45_LENGTH_BOOT_ROM;
499 if( ctrlParms.strLen <= 0 || ctrlParms.strLen > allowedSize)
501 printk("Illegal root file system size [%d]. Size allowed: [%d]\n",
502 ctrlParms.strLen, allowedSize);
506 ret = kerSysBcmImageSet(ctrlParms.offset, ctrlParms.string, ctrlParms.strLen);
507 kerSysMipsSoftReset();
510 case BCM_IMAGE_TECOM: //tecom: to upload image by pieces
511 allowedSize = (int) flash_get_total_size() - \
512 FLASH_RESERVED_AT_END - TAG_LEN - FLASH45_LENGTH_BOOT_ROM;
513 if( ctrlParms.strLen <= 0 || ctrlParms.strLen > allowedSize)
515 printk("Illegal root file system size [%d]. Size allowed: [%d]\n",
516 ctrlParms.strLen, allowedSize);
520 ret = kerSysBcmImageSet(ctrlParms.offset, ctrlParms.string, ctrlParms.strLen);
521 /*kerSysMipsSoftReset();*/
524 case BCM_IMAGE_KERNEL: // not used for now.
526 case BCM_IMAGE_WHOLE:
527 if(ctrlParms.strLen <= 0)
529 printk("Illegal flash image size [%d].\n", ctrlParms.strLen);
534 // save NVRAM data into a local structure
535 memcpy( &SaveNvramData, pNvramData, sizeof(NVRAM_DATA) );
537 ret = kerSysBcmImageSet(ctrlParms.offset, ctrlParms.string, ctrlParms.strLen);
539 // if nvram is not valid, restore the current nvram settings
540 if( BpSetBoardId( pNvramData->szBoardId ) != BP_SUCCESS &&
541 *(unsigned long *) pNvramData == NVRAM_DATA_ID )
543 kerSysNvRamSet((char *) &SaveNvramData, sizeof(SaveNvramData), 0);
546 kerSysMipsSoftReset();
551 printk("flash_ioctl_command: invalid command %d\n", ctrlParms.action);
554 ctrlParms.result = ret;
555 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
561 case BOARD_IOCTL_FLASH_READ:
562 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0)
564 switch (ctrlParms.action)
567 ret = kerSysScratchPadGet(ctrlParms.string, ctrlParms.buf, ctrlParms.offset);
571 ret = kerSysPersistentGet(ctrlParms.string, ctrlParms.strLen, ctrlParms.offset);
575 ret = kerSysNvRamGet(ctrlParms.string, ctrlParms.strLen, ctrlParms.offset);
579 ret = kerSysFlashSizeGet();
584 printk("Not supported. invalid command %d\n", ctrlParms.action);
587 ctrlParms.result = ret;
588 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
594 case BOARD_IOCTL_GET_NR_PAGES:
595 ctrlParms.result = nr_free_pages() + get_page_cache_size();
596 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
600 case BOARD_IOCTL_DUMP_ADDR:
601 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0)
603 dumpaddr( (unsigned char *) ctrlParms.string, ctrlParms.strLen );
604 ctrlParms.result = 0;
605 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
612 case BOARD_IOCTL_SET_MEMORY:
613 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0)
615 unsigned long *pul = (unsigned long *) ctrlParms.string;
616 unsigned short *pus = (unsigned short *) ctrlParms.string;
617 unsigned char *puc = (unsigned char *) ctrlParms.string;
618 switch( ctrlParms.strLen )
621 *pul = (unsigned long) ctrlParms.offset;
624 *pus = (unsigned short) ctrlParms.offset;
627 *puc = (unsigned char) ctrlParms.offset;
630 dumpaddr( (unsigned char *) ctrlParms.string, sizeof(long) );
631 ctrlParms.result = 0;
632 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
639 case BOARD_IOCTL_MIPS_SOFT_RESET:
640 kerSysMipsSoftReset();
643 case BOARD_IOCTL_LED_CTRL:
644 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0)
646 kerSysLedCtrl((BOARD_LED_NAME)ctrlParms.strLen, (BOARD_LED_STATE)ctrlParms.offset);
651 case BOARD_IOCTL_GET_ID:
652 if (copy_from_user((void*)&ctrlParms, (void*)arg,
653 sizeof(ctrlParms)) == 0)
655 if( ctrlParms.string )
657 char *p = (char *) get_system_type();
658 if( strlen(p) + 1 < ctrlParms.strLen )
659 ctrlParms.strLen = strlen(p) + 1;
660 __copy_to_user(ctrlParms.string, p, ctrlParms.strLen);
663 ctrlParms.result = 0;
664 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms,
665 sizeof(BOARD_IOCTL_PARMS));
669 case BOARD_IOCTL_GET_MAC_ADDRESS:
670 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0)
672 ctrlParms.result = kerSysGetMacAddress( ucaMacAddr,
675 if( ctrlParms.result == 0 )
677 __copy_to_user(ctrlParms.string, ucaMacAddr,
681 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms,
682 sizeof(BOARD_IOCTL_PARMS));
689 case BOARD_IOCTL_RELEASE_MAC_ADDRESS:
690 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0)
692 if (copy_from_user((void*)ucaMacAddr, (void*)ctrlParms.string, \
693 NVRAM_MAC_ADDRESS_LEN) == 0)
695 ctrlParms.result = kerSysReleaseMacAddress( ucaMacAddr );
699 ctrlParms.result = -EACCES;
702 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms,
703 sizeof(BOARD_IOCTL_PARMS));
710 case BOARD_IOCTL_GET_PSI_SIZE:
711 ctrlParms.result = (int) g_pNvramInfo->ulPsiSize;
712 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
716 case BOARD_IOCTL_GET_SDRAM_SIZE:
717 ctrlParms.result = (int) g_pNvramInfo->ulSdramSize;
718 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
722 case BOARD_IOCTL_GET_BASE_MAC_ADDRESS:
723 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0)
725 __copy_to_user(ctrlParms.string, g_pNvramInfo->ucaBaseMacAddr, NVRAM_MAC_ADDRESS_LEN);
726 ctrlParms.result = 0;
728 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms,
729 sizeof(BOARD_IOCTL_PARMS));
736 case BOARD_IOCTL_GET_CHIP_ID:
737 ctrlParms.result = (int) (PERF->RevID & 0xFFFF0000) >> 16;
738 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
742 case BOARD_IOCTL_GET_NUM_ENET: {
743 ETHERNET_MAC_INFO EnetInfos[BP_MAX_ENET_MACS];
745 if (BpGetEthernetMacInfo(EnetInfos, BP_MAX_ENET_MACS) == BP_SUCCESS) {
746 for( i = 0; i < BP_MAX_ENET_MACS; i++) {
747 if (EnetInfos[i].ucPhyType != BP_ENET_NO_PHY) {
751 ctrlParms.result = numeth;
752 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
761 case BOARD_IOCTL_GET_CFE_VER:
762 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
763 char *vertag = (char *)(FLASH_BASE + CFE_VERSION_OFFSET);
764 if (ctrlParms.strLen < CFE_VERSION_SIZE) {
765 ctrlParms.result = 0;
766 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
769 else if (strncmp(vertag, "cfe-v", 5)) { // no tag info in flash
770 ctrlParms.result = 0;
771 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
775 ctrlParms.result = 1;
776 __copy_to_user(ctrlParms.string, vertag+CFE_VERSION_MARK_SIZE, CFE_VERSION_SIZE);
777 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
786 case BOARD_IOCTL_GET_ENET_CFG:
787 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) {
788 ETHERNET_MAC_INFO EnetInfos[BP_MAX_ENET_MACS];
790 if (BpGetEthernetMacInfo(EnetInfos, BP_MAX_ENET_MACS) == BP_SUCCESS) {
791 if (ctrlParms.strLen == sizeof(EnetInfos)) {
792 __copy_to_user(ctrlParms.string, EnetInfos, sizeof(EnetInfos));
793 ctrlParms.result = 0;
794 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
805 /* Tommy, add two functions */
806 case BOARD_IOCTL_GET_GPIO:
807 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0)
813 if (ctrlParms.strLen >= 32)
815 i = ctrlParms.strLen - 32;
816 j = GPIO->GPIOio_high;
820 i = ctrlParms.strLen;
824 *ctrlParms.buf = (char) (j?1:0);
825 ctrlParms.result = 0;
826 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
833 case BOARD_IOCTL_SET_GPIO:
834 if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0)
840 if (ctrlParms.strLen >= 32)
842 i = ctrlParms.strLen - 32;
844 GPIO->GPIODir_high |= (1 << i); //set to R/W pin
845 if (ctrlParms.offset)
846 GPIO->GPIOio_high |= (1 << i);
849 j = (1 << i) ^ 0xffffffff;
850 GPIO->GPIOio_high &= j;
855 i = ctrlParms.strLen;
857 GPIO->GPIODir |= (1 << i); //set to R/W pin
858 if (ctrlParms.offset)
859 GPIO->GPIOio |= (1 << i);
862 j = (1 << i) ^ 0xffffffff;
866 ctrlParms.result = 0;
867 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
874 case BOARD_IOCTL_GET_RESET_STATUS:
877 unsigned long gpio_mask;
878 volatile unsigned long *gpio_reg;
880 if( BpGetPressAndHoldResetGpio( &gpio ) == BP_SUCCESS )
882 gpio_mask = GPIO_NUM_TO_MASK(gpio);
883 gpio_reg = &GPIO->GPIOio;
885 if( (gpio & ~BP_ACTIVE_MASK) >= 32 )
887 gpio_mask = GPIO_NUM_TO_MASK_HIGH(gpio);
888 gpio_reg = &GPIO->GPIOio_high;
891 ctrlParms.result = (int) *gpio_reg & gpio_mask;
892 __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS));
902 ctrlParms.result = 0;
903 printk("board_ioctl: invalid command %x, cmd %d .\n",command,_IOC_NR(command));
913 /***************************************************************************
914 * MACRO to call driver initialization and cleanup functions.
915 ***************************************************************************/
916 module_init( brcm_board_init );
917 module_exit( brcm_board_cleanup );
919 EXPORT_SYMBOL(kerSysNvRamGet);
920 EXPORT_SYMBOL(dumpaddr);
921 EXPORT_SYMBOL(kerSysGetMacAddress);
922 EXPORT_SYMBOL(kerSysReleaseMacAddress);
923 EXPORT_SYMBOL(kerSysGetSdramSize);
924 EXPORT_SYMBOL(kerSysLedCtrl);
925 EXPORT_SYMBOL(kerSysLedRegisterHwHandler);
926 EXPORT_SYMBOL(BpGetBoardIds);
927 EXPORT_SYMBOL(BpGetSdramSize);
928 EXPORT_SYMBOL(BpGetPsiSize);
929 EXPORT_SYMBOL(BpGetEthernetMacInfo);
930 EXPORT_SYMBOL(BpGetRj11InnerOuterPairGpios);
931 EXPORT_SYMBOL(BpGetPressAndHoldResetGpio);
932 EXPORT_SYMBOL(BpGetVoipResetGpio);
933 EXPORT_SYMBOL(BpGetVoipIntrGpio);
934 EXPORT_SYMBOL(BpGetPcmciaResetGpio);
935 EXPORT_SYMBOL(BpGetRtsCtsUartGpios);
936 EXPORT_SYMBOL(BpGetAdslLedGpio);
937 EXPORT_SYMBOL(BpGetAdslFailLedGpio);
938 EXPORT_SYMBOL(BpGetWirelessLedGpio);
939 EXPORT_SYMBOL(BpGetUsbLedGpio);
940 EXPORT_SYMBOL(BpGetHpnaLedGpio);
941 EXPORT_SYMBOL(BpGetWanDataLedGpio);
942 EXPORT_SYMBOL(BpGetPppLedGpio);
943 EXPORT_SYMBOL(BpGetPppFailLedGpio);
944 EXPORT_SYMBOL(BpGetVoipLedGpio);
945 EXPORT_SYMBOL(BpGetWirelessExtIntr);
946 EXPORT_SYMBOL(BpGetAdslDyingGaspExtIntr);
947 EXPORT_SYMBOL(BpGetVoipExtIntr);
948 EXPORT_SYMBOL(BpGetHpnaExtIntr);
949 EXPORT_SYMBOL(BpGetHpnaChipSelect);
950 EXPORT_SYMBOL(BpGetVoipChipSelect);