diff options
Diffstat (limited to 'target/linux')
-rw-r--r-- | target/linux/brcm63xx-2.6/patches/001-brcm_boards.patch | 9216 |
1 files changed, 9216 insertions, 0 deletions
diff --git a/target/linux/brcm63xx-2.6/patches/001-brcm_boards.patch b/target/linux/brcm63xx-2.6/patches/001-brcm_boards.patch index 79913989f..9e6679898 100644 --- a/target/linux/brcm63xx-2.6/patches/001-brcm_boards.patch +++ b/target/linux/brcm63xx-2.6/patches/001-brcm_boards.patch @@ -1,33 +1,9249 @@ +diff -urN linux-2.6.17/arch/mips/brcm-boards/bcm963xx/bcm63xx_flash.c linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/bcm63xx_flash.c +--- linux-2.6.17/arch/mips/brcm-boards/bcm963xx/bcm63xx_flash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/bcm63xx_flash.c 2006-08-03 16:36:58.000000000 +0200 +@@ -0,0 +1,775 @@ ++/* ++<:copyright-gpl ++ Copyright 2002 Broadcom Corp. All Rights Reserved. ++ ++ This program is free software; you can distribute it and/or modify it ++ under the terms of the GNU General Public License (Version 2) as ++ published by the Free Software Foundation. ++ ++ This program is distributed in the hope it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++:> ++*/ ++/* ++ *************************************************************************** ++ * File Name : bcm63xx_flash.c ++ * ++ * Description: This file contains the flash device driver APIs for bcm63xx board. ++ * ++ * Created on : 8/10/2002 seanl: use cfiflash.c, cfliflash.h (AMD specific) ++ * ++ ***************************************************************************/ ++ ++ ++/* Includes. */ ++#include <linux/fs.h> ++#include <linux/capability.h> ++#include <linux/slab.h> ++#include <linux/errno.h> ++#include <linux/module.h> ++#include <asm/uaccess.h> ++ ++#include <bcm_map_part.h> ++#include <board.h> ++#define BCMTAG_EXE_USE ++#include <bcmTag.h> ++#include "cfiflash.h" ++#include "boardparms.h" ++ ++//#define DEBUG_FLASH ++ ++static FLASH_ADDR_INFO fInfo; ++static int flashInitialized = 0; ++ ++void *retriedKmalloc(size_t size) ++{ ++ void *pBuf; ++ int tryCount = 0; ++ ++ // try 1000 times before quit ++ while (((pBuf = kmalloc(size, GFP_KERNEL)) == NULL) && (tryCount++ < 1000)) ++ { ++ current->state = TASK_INTERRUPTIBLE; ++ schedule_timeout(HZ/10); ++ } ++ if (tryCount >= 1000) ++ pBuf = NULL; ++ else ++ memset(pBuf, 0, size); ++ ++ return pBuf; ++} ++ ++void retriedKfree(void *pBuf) ++{ ++ kfree(pBuf); ++} ++ ++/*************************************************************************** ++// Function Name: getCrc32 ++// Description : caculate the CRC 32 of the given data. ++// Parameters : pdata - array of data. ++// size - number of input data bytes. ++// crc - either CRC32_INIT_VALUE or previous return value. ++// Returns : crc. ++****************************************************************************/ ++UINT32 getCrc32(byte *pdata, UINT32 size, UINT32 crc) ++{ ++ while (size-- > 0) ++ crc = (crc >> 8) ^ Crc32_table[(crc ^ *pdata++) & 0xff]; ++ ++ return crc; ++} ++ ++// get the nvram start addr ++// ++unsigned long get_nvram_start_addr(void) ++{ ++ return ((unsigned long) ++ (flash_get_memptr(fInfo.flash_nvram_start_blk) + fInfo.flash_nvram_blk_offset)); ++} ++ ++// get the scratch_pad start addr ++// ++unsigned long get_scratch_pad_start_addr(void) ++{ ++ return ((unsigned long) ++ (flash_get_memptr(fInfo.flash_scratch_pad_start_blk) + fInfo.flash_scratch_pad_blk_offset)); ++} ++ ++ ++ ++/* ********************************************************************* ++ * kerSysImageTagGet() ++ * Get the image tag ++ * Input parameters: ++ * none ++ * Return value: ++ * point to tag -- Found ++ * NULL -- failed ++ ********************************************************************* */ ++PFILE_TAG kerSysImageTagGet(void) ++{ ++ int i; ++ int totalBlks = flash_get_numsectors(); ++ UINT32 crc; ++ unsigned char *sectAddr; ++ PFILE_TAG pTag; ++ ++#if defined(DEBUG_FLASH) ++ printk("totalblks in tagGet=%d\n", totalBlks); ++#endif ++ + // start from 2nd blk, assume 1st one is always CFE ++ for (i = 1; i < totalBlks; i++) ++ { ++ sectAddr = flash_get_memptr((byte) i); ++ crc = CRC32_INIT_VALUE; ++ crc = getCrc32(sectAddr, (UINT32)TAG_LEN-TOKEN_LEN, crc); ++ pTag = (PFILE_TAG) sectAddr; ++ ++#if defined(DEBUG_FLASH) ++ printk("Check Tag crc on blk [%d]\n", i); ++#endif ++ ++ if (crc == (UINT32)(*(UINT32*)(pTag->tagValidationToken))) ++ return pTag; ++ } ++ ++ return (PFILE_TAG) NULL; ++} ++ ++// Initialize the flash and fill out the fInfo structure ++void kerSysFlashInit( void ) ++{ ++ int i = 0; ++ int totalBlks = 0; ++ int totalSize = 0; ++ int startAddr = 0; ++ int usedBlkSize = 0; ++ NVRAM_DATA nvramData; ++ UINT32 crc = CRC32_INIT_VALUE, savedCrc; ++ PFILE_TAG pTag = NULL; ++ unsigned long kernelEndAddr = 0; ++ unsigned long spAddr = 0; ++ ++ if (flashInitialized) ++ return; ++ ++ flashInitialized = 1; ++ flash_init(); ++ ++ totalBlks = flash_get_numsectors(); ++ totalSize = flash_get_total_size(); ++ ++ printk("Total Flash size: %dK with %d sectors\n", totalSize/1024, totalBlks); ++ ++ /* nvram is always at the end of flash */ ++ fInfo.flash_nvram_length = FLASH45_LENGTH_NVRAM; ++ fInfo.flash_nvram_start_blk = 0; /* always the first block */ ++ fInfo.flash_nvram_number_blk = 1; /*always fits in the first block */ ++ fInfo.flash_nvram_blk_offset = NVRAM_DATA_OFFSET; ++ ++ // check nvram CRC ++ memcpy((char *)&nvramData, (char *)get_nvram_start_addr(), sizeof(NVRAM_DATA)); ++ savedCrc = nvramData.ulCheckSum; ++ nvramData.ulCheckSum = 0; ++ crc = getCrc32((char *)&nvramData, (UINT32) sizeof(NVRAM_DATA), crc); ++ ++ BpSetBoardId( nvramData.szBoardId ); ++ ++ fInfo.flash_persistent_length = NVRAM_PSI_DEFAULT; ++ if (savedCrc != crc) ++ { ++ printk("***Board is not initialized****: Using the default PSI size: %d\n", ++ fInfo.flash_persistent_length); ++ } ++ else ++ { ++ unsigned long ulPsiSize; ++ if( BpGetPsiSize( &ulPsiSize ) == BP_SUCCESS ) ++ fInfo.flash_persistent_length = ulPsiSize; ++ else ++ { ++ printk("***Board id is not set****: Using the default PSI size: %d\n", ++ fInfo.flash_persistent_length); ++ } ++ } ++ ++ fInfo.flash_persistent_length *= ONEK; ++ startAddr = totalSize - fInfo.flash_persistent_length; ++ fInfo.flash_persistent_start_blk = flash_get_blk(startAddr+FLASH_BASE_ADDR_REG); ++ fInfo.flash_persistent_number_blk = totalBlks - fInfo.flash_persistent_start_blk; ++ // save abs SP address (Scratch Pad). it is before PSI ++ spAddr = startAddr - SP_MAX_LEN ; ++ // find out the offset in the start_blk ++ usedBlkSize = 0; ++ for (i = fInfo.flash_persistent_start_blk; ++ i < (fInfo.flash_persistent_start_blk + fInfo.flash_persistent_number_blk); i++) ++ { ++ usedBlkSize += flash_get_sector_size((byte) i); ++ } ++ fInfo.flash_persistent_blk_offset = usedBlkSize - fInfo.flash_persistent_length; ++ ++ // get the info for sp ++ if (!(pTag = kerSysImageTagGet())) ++ { ++ printk("Failed to read image tag from flash\n"); ++ return; ++ } ++ kernelEndAddr = (unsigned long) simple_strtoul(pTag->kernelAddress, NULL, 10) + \ ++ (unsigned long) simple_strtoul(pTag->kernelLen, NULL, 10); ++ ++ // make suer sp does not share kernel block ++ fInfo.flash_scratch_pad_start_blk = flash_get_blk(spAddr+FLASH_BASE_ADDR_REG); ++ if (fInfo.flash_scratch_pad_start_blk != flash_get_blk(kernelEndAddr)) ++ { ++ fInfo.flash_scratch_pad_length = SP_MAX_LEN; ++ if (fInfo.flash_persistent_start_blk == fInfo.flash_scratch_pad_start_blk) // share blk ++ { ++#if 1 /* do not used scratch pad unless it's in its own sector */ ++ printk("Scratch pad is not used for this flash part.\n"); ++ fInfo.flash_scratch_pad_length = 0; // no sp ++#else /* allow scratch pad to share a sector with another section such as PSI */ ++ fInfo.flash_scratch_pad_number_blk = 1; ++ fInfo.flash_scratch_pad_blk_offset = fInfo.flash_persistent_blk_offset - fInfo.flash_scratch_pad_length; ++#endif ++ } ++ else // on different blk ++ { ++ fInfo.flash_scratch_pad_number_blk = fInfo.flash_persistent_start_blk\ ++ - fInfo.flash_scratch_pad_start_blk; ++ // find out the offset in the start_blk ++ usedBlkSize = 0; ++ for (i = fInfo.flash_scratch_pad_start_blk; ++ i < (fInfo.flash_scratch_pad_start_blk + fInfo.flash_scratch_pad_number_blk); i++) ++ usedBlkSize += flash_get_sector_size((byte) i); ++ fInfo.flash_scratch_pad_blk_offset = usedBlkSize - fInfo.flash_scratch_pad_length; ++ } ++ } ++ else ++ { ++ printk("No flash for scratch pad!\n"); ++ fInfo.flash_scratch_pad_length = 0; // no sp ++ } ++ ++#if defined(DEBUG_FLASH) ++ printk("fInfo.flash_scratch_pad_start_blk = %d\n", fInfo.flash_scratch_pad_start_blk); ++ printk("fInfo.flash_scratch_pad_number_blk = %d\n", fInfo.flash_scratch_pad_number_blk); ++ printk("fInfo.flash_scratch_pad_length = 0x%x\n", fInfo.flash_scratch_pad_length); ++ printk("fInfo.flash_scratch_pad_blk_offset = 0x%x\n", (unsigned int)fInfo.flash_scratch_pad_blk_offset); ++ ++ printk("fInfo.flash_nvram_start_blk = %d\n", fInfo.flash_nvram_start_blk); ++ printk("fInfo.flash_nvram_blk_offset = 0x%x\n", (unsigned int)fInfo.flash_nvram_blk_offset); ++ printk("fInfo.flash_nvram_number_blk = %d\n", fInfo.flash_nvram_number_blk); ++ ++ printk("psi startAddr = %x\n", startAddr+FLASH_BASE_ADDR_REG); ++ printk("fInfo.flash_persistent_start_blk = %d\n", fInfo.flash_persistent_start_blk); ++ printk("fInfo.flash_persistent_blk_offset = 0x%x\n", (unsigned int)fInfo.flash_persistent_blk_offset); ++ printk("fInfo.flash_persistent_number_blk = %d\n", fInfo.flash_persistent_number_blk); ++#endif ++ ++} ++ ++ ++ ++/*********************************************************************** ++ * Function Name: kerSysFlashAddrInfoGet ++ * Description : Fills in a structure with information about the NVRAM ++ * and persistent storage sections of flash memory. ++ * Fro physmap.c to mount the fs vol. ++ * Returns : None. ++ ***********************************************************************/ ++void kerSysFlashAddrInfoGet(PFLASH_ADDR_INFO pflash_addr_info) ++{ ++ pflash_addr_info->flash_nvram_blk_offset = fInfo.flash_nvram_blk_offset; ++ pflash_addr_info->flash_nvram_length = fInfo.flash_nvram_length; ++ pflash_addr_info->flash_nvram_number_blk = fInfo.flash_nvram_number_blk; ++ pflash_addr_info->flash_nvram_start_blk = fInfo.flash_nvram_start_blk; ++ pflash_addr_info->flash_persistent_blk_offset = fInfo.flash_persistent_blk_offset; ++ pflash_addr_info->flash_persistent_length = fInfo.flash_persistent_length; ++ pflash_addr_info->flash_persistent_number_blk = fInfo.flash_persistent_number_blk; ++ pflash_addr_info->flash_persistent_start_blk = fInfo.flash_persistent_start_blk; ++} ++ ++ ++// get shared blks into *** pTempBuf *** which has to be released bye the caller! ++// return: if pTempBuf != NULL, poits to the data with the dataSize of the buffer ++// !NULL -- ok ++// NULL -- fail ++static char *getSharedBlks(int start_blk, int end_blk) ++{ ++ int i = 0; ++ int usedBlkSize = 0; ++ int sect_size = 0; ++ char *pTempBuf = NULL; ++ char *pBuf = NULL; ++ ++ for (i = start_blk; i < end_blk; i++) ++ usedBlkSize += flash_get_sector_size((byte) i); ++ ++#if defined(DEBUG_FLASH) ++ printk("usedBlkSize = %d\n", usedBlkSize); ++#endif ++ ++ if ((pTempBuf = (char *) retriedKmalloc(usedBlkSize)) == NULL) ++ { ++ printk("failed to allocate memory with size: %d\n", usedBlkSize); ++ return pTempBuf; ++ } ++ ++ pBuf = pTempBuf; ++ for (i = start_blk; i < end_blk; i++) ++ { ++ sect_size = flash_get_sector_size((byte) i); ++ ++#if defined(DEBUG_FLASH) ++ printk("i = %d, sect_size = %d, end_blk = %d\n", i, sect_size, end_blk); ++#endif ++ flash_read_buf((byte)i, 0, pBuf, sect_size); ++ pBuf += sect_size; ++ } ++ ++ return pTempBuf; ++} ++ ++ ++ ++// Set the pTempBuf to flash from start_blk to end_blk ++// return: ++// 0 -- ok ++// -1 -- fail ++static int setSharedBlks(int start_blk, int end_blk, char *pTempBuf) ++{ ++ int i = 0; ++ int sect_size = 0; ++ int sts = 0; ++ char *pBuf = pTempBuf; ++ ++ for (i = start_blk; i < end_blk; i++) ++ { ++ sect_size = flash_get_sector_size((byte) i); ++ flash_sector_erase_int(i); ++ if (flash_write_buf(i, 0, pBuf, sect_size) != sect_size) ++ { ++ printk("Error writing flash sector %d.", i); ++ sts = -1; ++ break; ++ } ++ pBuf += sect_size; ++ } ++ ++ return sts; ++} ++ ++ ++ ++/******************************************************************************* ++ * NVRAM functions ++ *******************************************************************************/ ++ ++// get nvram data ++// return: ++// 0 - ok ++// -1 - fail ++int kerSysNvRamGet(char *string, int strLen, int offset) ++{ ++ char *pBuf = NULL; ++ ++ if (!flashInitialized) ++ kerSysFlashInit(); ++ ++ if (strLen > FLASH45_LENGTH_NVRAM) ++ return -1; ++ ++ if ((pBuf = getSharedBlks(fInfo.flash_nvram_start_blk, ++ (fInfo.flash_nvram_start_blk + fInfo.flash_nvram_number_blk))) == NULL) ++ return -1; ++ ++ // get string off the memory buffer ++ memcpy(string, (pBuf + fInfo.flash_nvram_blk_offset + offset), strLen); ++ ++ retriedKfree(pBuf); ++ ++ return 0; ++} ++ ++ ++// set nvram ++// return: ++// 0 - ok ++// -1 - fail ++int kerSysNvRamSet(char *string, int strLen, int offset) ++{ ++ int sts = 0; ++ char *pBuf = NULL; ++ ++ if (strLen > FLASH45_LENGTH_NVRAM) ++ return -1; ++ ++ if ((pBuf = getSharedBlks(fInfo.flash_nvram_start_blk, ++ (fInfo.flash_nvram_start_blk + fInfo.flash_nvram_number_blk))) == NULL) ++ return -1; ++ ++ // set string to the memory buffer ++ memcpy((pBuf + fInfo.flash_nvram_blk_offset + offset), string, strLen); ++ ++ if (setSharedBlks(fInfo.flash_nvram_start_blk, ++ (fInfo.flash_nvram_number_blk + fInfo.flash_nvram_start_blk), pBuf) != 0) ++ sts = -1; ++ ++ retriedKfree(pBuf); ++ ++ return sts; ++} ++ ++ ++/*********************************************************************** ++ * Function Name: kerSysEraseNvRam ++ * Description : Erase the NVRAM storage section of flash memory. ++ * Returns : 1 -- ok, 0 -- fail ++ ***********************************************************************/ ++int kerSysEraseNvRam(void) ++{ ++ int sts = 1; ++ char *tempStorage = retriedKmalloc(FLASH45_LENGTH_NVRAM); ++ ++ // just write the whole buf with '0xff' to the flash ++ if (!tempStorage) ++ sts = 0; ++ else ++ { ++ memset(tempStorage, 0xff, FLASH45_LENGTH_NVRAM); ++ if (kerSysNvRamSet(tempStorage, FLASH45_LENGTH_NVRAM, 0) != 0) ++ sts = 0; ++ retriedKfree(tempStorage); ++ } ++ ++ return sts; ++} ++ ++ ++/******************************************************************************* ++ * PSI functions ++ *******************************************************************************/ ++// get psi data ++// return: ++// 0 - ok ++// -1 - fail ++int kerSysPersistentGet(char *string, int strLen, int offset) ++{ ++ char *pBuf = NULL; ++ ++ if (strLen > fInfo.flash_persistent_length) ++ return -1; ++ ++ if ((pBuf = getSharedBlks(fInfo.flash_persistent_start_blk, ++ (fInfo.flash_persistent_start_blk + fInfo.flash_persistent_number_blk))) == NULL) ++ return -1; ++ ++ // get string off the memory buffer ++ memcpy(string, (pBuf + fInfo.flash_persistent_blk_offset + offset), strLen); ++ ++ retriedKfree(pBuf); ++ ++ return 0; ++} ++ ++ ++// set psi ++// return: ++// 0 - ok ++// -1 - fail ++int kerSysPersistentSet(char *string, int strLen, int offset) ++{ ++ int sts = 0; ++ char *pBuf = NULL; ++ ++ if (strLen > fInfo.flash_persistent_length) ++ return -1; ++ ++ if ((pBuf = getSharedBlks(fInfo.flash_persistent_start_blk, ++ (fInfo.flash_persistent_start_blk + fInfo.flash_persistent_number_blk))) == NULL) ++ return -1; ++ ++ // set string to the memory buffer ++ memcpy((pBuf + fInfo.flash_persistent_blk_offset + offset), string, strLen); ++ ++ if (setSharedBlks(fInfo.flash_persistent_start_blk, ++ (fInfo.flash_persistent_number_blk + fInfo.flash_persistent_start_blk), pBuf) != 0) ++ sts = -1; ++ ++ retriedKfree(pBuf); ++ ++ return sts; ++} ++ ++ ++// flash bcm image ++// return: ++// 0 - ok ++// !0 - the sector number fail to be flashed (should not be 0) ++int kerSysBcmImageSet( int flash_start_addr, char *string, int size) ++{ ++ int sts; ++ int sect_size; ++ int blk_start; ++ int i; ++ char *pTempBuf = NULL; ++ int whole_image = 0; ++ ++ blk_start = flash_get_blk(flash_start_addr); ++ if( blk_start < 0 ) ++ return( -1 ); ++ ++ if (flash_start_addr == FLASH_BASE && size > FLASH45_LENGTH_BOOT_ROM) ++ whole_image = 1; ++ ++ /* write image to flash memory */ ++ do ++ { ++ sect_size = flash_get_sector_size(blk_start); ++// NOTE: for memory problem in multiple PVC configuration, temporary get rid of kmalloc this 64K for now. ++// if ((pTempBuf = (char *)retriedKmalloc(sect_size)) == NULL) ++// { ++// printk("Failed to allocate memory with size: %d. Reset the router...\n", sect_size); ++// kerSysMipsSoftReset(); // reset the board right away. ++// } ++ // for whole image, no check on psi ++ if (!whole_image && blk_start == fInfo.flash_persistent_start_blk) // share the blk with psi ++ { ++ if (size > (sect_size - fInfo.flash_persistent_length)) ++ { ++ printk("Image is too big\n"); ++ break; // image is too big. Can not overwrite to nvram ++ } ++ if ((pTempBuf = (char *)retriedKmalloc(sect_size)) == NULL) ++ { ++ printk("Failed to allocate memory with size: %d. Reset the router...\n", sect_size); ++ kerSysMipsSoftReset(); // reset the board right away. ++ } ++ flash_read_buf((byte)blk_start, 0, pTempBuf, sect_size); ++ if (copy_from_user((void *)pTempBuf,(void *)string, size) != 0) ++ break; // failed ? ++ flash_sector_erase_int(blk_start); // erase blk before flash ++ if (flash_write_buf(blk_start, 0, pTempBuf, sect_size) == sect_size) ++ size = 0; // break out and say all is ok ++ retriedKfree(pTempBuf); ++ break; ++ } ++ ++ flash_sector_erase_int(blk_start); // erase blk before flash ++ ++ if (sect_size > size) ++ { ++ if (size & 1) ++ size++; ++ sect_size = size; ++ } ++ ++ if ((i = flash_write_buf(blk_start, 0, string, sect_size)) != sect_size) { ++ break; ++ } ++ blk_start++; ++ string += sect_size; ++ size -= sect_size; ++ } while (size > 0); ++ ++ if (whole_image) ++ { ++ // If flashing a whole image, erase to end of flash. ++ int total_blks = flash_get_numsectors(); ++ while( blk_start < total_blks ) ++ { ++ flash_sector_erase_int(blk_start); ++ blk_start++; ++ } ++ } ++ if (pTempBuf) ++ retriedKfree(pTempBuf); ++ ++ if( size == 0 ) ++ sts = 0; // ok ++ else ++ sts = blk_start; // failed to flash this sector ++ ++ return sts; ++} ++ ++/******************************************************************************* ++ * SP functions ++ *******************************************************************************/ ++// get sp data. NOTE: memcpy work here -- not using copy_from/to_user ++// return: ++// 0 - ok ++// -1 - fail ++int kerSysScratchPadGet(char *tokenId, char *tokBuf, int bufLen) ++{ ++ PSP_HEADER pHead = NULL; ++ PSP_TOKEN pToken = NULL; ++ char *pBuf = NULL; ++ char *pShareBuf = NULL; ++ char *startPtr = NULL; ++ char *endPtr = NULL; ++ char *spEndPtr = NULL; ++ int sts = -1; ++ ++ if (fInfo.flash_scratch_pad_length == 0) ++ return sts; ++ ++ if (bufLen >= (fInfo.flash_scratch_pad_length - sizeof(SP_HEADER) - sizeof(SP_TOKEN))) ++ { ++ printk("Exceed scratch pad space by %d\n", bufLen - fInfo.flash_scratch_pad_length \ ++ - sizeof(SP_HEADER) - sizeof(SP_TOKEN)); ++ return sts; ++ } ++ ++ if ((pShareBuf = getSharedBlks(fInfo.flash_scratch_pad_start_blk, ++ (fInfo.flash_scratch_pad_start_blk + fInfo.flash_scratch_pad_number_blk))) == NULL) ++ return sts; ++ ++ // pBuf points to SP buf ++ pBuf = pShareBuf + fInfo.flash_scratch_pad_blk_offset; ++ ++ pHead = (PSP_HEADER) pBuf; ++ if (memcmp(pHead->SPMagicNum, MAGIC_NUMBER, MAGIC_NUM_LEN) != 0) ++ { ++ printk("Scrap pad is not initialized.\n"); ++ return sts; ++ } ++ ++ // search up to SPUsedLen for the token ++ startPtr = pBuf + sizeof(SP_HEADER); ++ endPtr = pBuf + pHead->SPUsedLen; ++ spEndPtr = pBuf + SP_MAX_LEN; ++ while (startPtr < endPtr && startPtr < spEndPtr) ++ { ++ pToken = (PSP_TOKEN) startPtr; ++ if (strncmp(pToken->tokenName, tokenId, TOKEN_NAME_LEN) == 0) ++ { ++ memcpy(tokBuf, startPtr + sizeof(SP_TOKEN), bufLen); ++ sts = 0; ++ break; ++ } ++ // get next token ++ startPtr += sizeof(SP_TOKEN) + pToken->tokenLen; ++ } ++ ++ retriedKfree(pShareBuf); ++ ++ return sts; ++} ++ ++ ++// set sp. NOTE: memcpy work here -- not using copy_from/to_user ++// return: ++// 0 - ok ++// -1 - fail ++int kerSysScratchPadSet(char *tokenId, char *tokBuf, int bufLen) ++{ ++ PSP_TOKEN pToken = NULL; ++ PSP_HEADER pHead = NULL; ++ char *pShareBuf = NULL; ++ char *pBuf = NULL; ++ SP_HEADER SPHead; ++ SP_TOKEN SPToken; ++ char *curPtr; ++ int sts = -1; ++ ++ if (fInfo.flash_scratch_pad_length == 0) ++ return sts; ++ ++ if (bufLen >= (fInfo.flash_scratch_pad_length - sizeof(SP_HEADER) - sizeof(SP_TOKEN))) ++ { ++ printk("Exceed scratch pad space by %d\n", bufLen - fInfo.flash_scratch_pad_length \ ++ - sizeof(SP_HEADER) - sizeof(SP_TOKEN)); ++ return sts; ++ } ++ ++ if ((pShareBuf = getSharedBlks(fInfo.flash_scratch_pad_start_blk, ++ (fInfo.flash_scratch_pad_start_blk + fInfo.flash_scratch_pad_number_blk))) == NULL) ++ return sts; ++ ++ // pBuf points to SP buf ++ pBuf = pShareBuf + fInfo.flash_scratch_pad_blk_offset; ++ pHead = (PSP_HEADER) pBuf; ++ ++ // form header info. SPUsedLen later on... ++ memset((char *)&SPHead, 0, sizeof(SP_HEADER)); ++ memcpy(SPHead.SPMagicNum, MAGIC_NUMBER, MAGIC_NUM_LEN); ++ SPHead.SPVersion = SP_VERSION; ++ ++ // form token info. ++ memset((char*)&SPToken, 0, sizeof(SP_TOKEN)); ++ strncpy(SPToken.tokenName, tokenId, TOKEN_NAME_LEN - 1); ++ SPToken.tokenLen = bufLen; ++ if (memcmp(pHead->SPMagicNum, MAGIC_NUMBER, MAGIC_NUM_LEN) != 0) ++ { ++ // new sp, so just flash the token ++ printk("No Scrap pad found. Initialize scratch pad...\n"); ++ SPHead.SPUsedLen = sizeof(SP_HEADER) + sizeof(SP_TOKEN) + bufLen; ++ memcpy(pBuf, (char *)&SPHead, sizeof(SP_HEADER)); ++ curPtr = pBuf + sizeof(SP_HEADER); ++ memcpy(curPtr, (char *)&SPToken, sizeof(SP_TOKEN)); ++ curPtr += sizeof(SP_TOKEN); ++ memcpy(curPtr, tokBuf, bufLen); ++ } ++ else ++ { ++ // need search for the token, if exist with same size overwrite it. if sizes differ, ++ // move over the later token data over and put the new one at the end ++ char *endPtr = pBuf + pHead->SPUsedLen; ++ char *spEndPtr = pBuf + SP_MAX_LEN; ++ curPtr = pBuf + sizeof(SP_HEADER); ++ while (curPtr < endPtr && curPtr < spEndPtr) ++ { ++ pToken = (PSP_TOKEN) curPtr; ++ if (strncmp(pToken->tokenName, tokenId, TOKEN_NAME_LEN) == 0) ++ { ++ if (pToken->tokenLen == bufLen) // overwirte it ++ { ++ memcpy((curPtr+sizeof(SP_TOKEN)), tokBuf, bufLen); ++ break; ++ } ++ else // move later data over and put the new token at the end ++ { ++ memcpy((curPtr+sizeof(SP_TOKEN)), tokBuf, bufLen); // ~~~ ++ break; ++ } ++ } ++ else // not same token ~~~ ++ { ++ } ++ // get next token ++ curPtr += sizeof(SP_TOKEN) + pToken->tokenLen; ++ } // end while ++ SPHead.SPUsedLen = sizeof(SP_HEADER) + sizeof(SP_TOKEN) + bufLen; // ~~~ ++ if (SPHead.SPUsedLen > SP_MAX_LEN) ++ { ++ printk("No more Scratch pad space left! Over limit by %d bytes\n", SPHead.SPUsedLen - SP_MAX_LEN); ++ return sts; ++ } ++ ++ } // else if not new sp ++ ++ sts = setSharedBlks(fInfo.flash_scratch_pad_start_blk, ++ (fInfo.flash_scratch_pad_number_blk + fInfo.flash_scratch_pad_start_blk), pShareBuf); ++ ++ retriedKfree(pShareBuf); ++ ++ return sts; ++ ++ ++} ++ ++int kerSysFlashSizeGet(void) ++{ ++ return flash_get_total_size(); ++} ++ +diff -urN linux-2.6.17/arch/mips/brcm-boards/bcm963xx/bcm63xx_led.c linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/bcm63xx_led.c +--- linux-2.6.17/arch/mips/brcm-boards/bcm963xx/bcm63xx_led.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/bcm63xx_led.c 2006-08-03 16:36:58.000000000 +0200 +@@ -0,0 +1,582 @@ ++/* ++<:copyright-gpl ++ Copyright 2002 Broadcom Corp. All Rights Reserved. ++ ++ This program is free software; you can distribute it and/or modify it ++ under the terms of the GNU General Public License (Version 2) as ++ published by the Free Software Foundation. ++ ++ This program is distributed in the hope it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++:> ++*/ ++/*************************************************************************** ++ * File Name : bcm63xx_led.c ++ * ++ * Description: ++ * ++ * This file contains bcm963xx board led control API functions. ++ * ++ * To use it, do the following ++ * ++ * 1). define in the board.c the following led mappping (this is for 6345GW board): ++ * const LED_MAP_PAIR cLedMapping45GW[] = ++ * { // led name Initial state physical pin (ledMask) ++ * {kLedUsb, kLedStateOff, GPIO_LED_PIN_7}, ++ * {kLedAdsl, kLedStateOff, GPIO_LED_PIN_8}, ++ * {kLedPPP, kLedStateOff, GPIO_LED_PIN_9}, // PPP and WanData share PIN_9 ++ * {kLedWanData, kLedStateOff, GPIO_LED_PIN_9}, ++ * {kLedWireless, kLedStateOff, GPIO_LED_PIN_10}, ++ * {kLedEnd, kLedStateOff, 0 } // NOTE: kLedEnd has to be at the end. ++ * ++ * 2). };To initialize led API and initial state of the leds, call the following function with the mapping ++ * pointer from the above struct ++ * ++ * boardLedInit((PLED_MAP_PAIR) &cLedMapping45R); ++ * ++ * 3). Sample call for kernel mode: ++ * ++ * kerSysLedCtrl(kLedAdsl, kLedStateBlinkOnce); // kLedxxx defines in board.h ++ * ++ * 4). Sample call for user mode ++ * ++ * sysLedCtrl(kLedAdsl, kLedStateBlinkOnce); // kLedxxx defines in board_api.h ++ * ++ * ++ * Created on : 10/28/2002 seanl ++ * ++ ***************************************************************************/ ++ ++/* Includes. */ ++#include <linux/init.h> ++#include <linux/fs.h> ++#include <linux/capability.h> ++#include <linux/slab.h> ++#include <linux/errno.h> ++#include <linux/module.h> ++#include <linux/netdevice.h> ++#include <asm/uaccess.h> ++ ++#include <bcm_map_part.h> ++#include <board.h> ++ ++#define k100ms (HZ / 10) // ~100 ms ++#define kFastBlinkCount 0 // ~100ms ++#define kSlowBlinkCount 5 // ~600ms ++ ++#define MAX_VIRT_LEDS 12 ++ ++// uncomment // for debug led ++//#define DEBUG_LED ++ ++// global variables: ++struct timer_list gLedTimer; ++int gTimerOn = FALSE; ++int gLedCount = 0; ++ ++typedef struct ledinfo ++{ ++ unsigned short ledMask; // mask for led: ie. giop 10 = 0x0400 ++ unsigned short ledActiveLow; // GPIO bit reset to turn on LED ++ unsigned short ledMaskFail; // mask for led: ie. giop 10 = 0x0400 ++ unsigned short ledActiveLowFail;// GPIO bit reset to turn on LED ++ BOARD_LED_STATE ledState; // current led state ++ BOARD_LED_STATE savedLedState; // used in blink once for restore to the orignal ledState ++ int blinkCountDown; // if == 0, do blink (toggle). Is assgined value and dec by 1 at each timer. ++} LED_INFO, *PLED_INFO; ++ ++static PLED_INFO gLed = NULL; ++static PLED_INFO gpVirtLeds[MAX_VIRT_LEDS]; ++static HANDLE_LED_FUNC gLedHwFunc[MAX_VIRT_LEDS]; ++static HANDLE_LED_FUNC gLedHwFailFunc[MAX_VIRT_LEDS]; ++ ++#if 0 /* BROKEN */ ++#if defined(CONFIG_BCM96348) || defined(CONFIG_BCM96338) ++static int gLedOffInBridgeMode = 1; ++#elif defined(CONFIG_BCM96345) ++static int gLedOffInBridgeMode = 0; ++#endif ++#endif ++ ++void ledTimerExpire(void); ++int initLedInfo( PLED_MAP_PAIR pCurMap, PLED_INFO pCurLed ); ++ ++//************************************************************************************** ++// LED operations ++//************************************************************************************** ++ ++// turn led on and set the ledState ++void ledOn(PLED_INFO pLed) ++{ ++ if( pLed->ledMask ) ++ { ++ GPIO->GPIODir |= pLed->ledMask; // turn on the direction bit in case was turned off by some one ++ if( pLed->ledActiveLow ) ++ GPIO->GPIOio &= ~pLed->ledMask; // turn on the led ++ else ++ GPIO->GPIOio |= pLed->ledMask; // turn on the led ++ pLed->ledState = pLed->savedLedState = kLedStateOn; ++ } ++} ++ ++ ++// turn led off and set the ledState ++void ledOff(PLED_INFO pLed) ++{ ++ if( pLed->ledMask ) ++ { ++ GPIO->GPIODir |= pLed->ledMask; // turn on the direction bit in case was turned off by some one ++ if( pLed->ledActiveLow ) ++ GPIO->GPIOio |= pLed->ledMask; // turn off the led ++ else ++ GPIO->GPIOio &= ~pLed->ledMask; // turn off the led ++ pLed->ledState = pLed->savedLedState = kLedStateOff; ++ } ++} ++ ++// turn led on and set the ledState ++void ledOnFail(PLED_INFO pLed) ++{ ++ if( pLed->ledMaskFail ) ++ { ++ GPIO->GPIODir |= pLed->ledMaskFail; // turn on the direction bit in case was turned off by some one ++ if( pLed->ledActiveLowFail ) ++ GPIO->GPIOio &= ~pLed->ledMaskFail;// turn on the led ++ else ++ GPIO->GPIOio |= pLed->ledMaskFail; // turn on the led ++ pLed->ledState = pLed->savedLedState = kLedStateFail; ++ } ++} ++ ++ ++// turn led off and set the ledState ++void ledOffFail(PLED_INFO pLed) ++{ ++ if( pLed->ledMaskFail ) ++ { ++ GPIO->GPIODir |= pLed->ledMaskFail; // turn on the direction bit in case was turned off by some one ++ if( pLed->ledActiveLowFail ) ++ GPIO->GPIOio |= pLed->ledMaskFail; // turn off the led ++ else ++ GPIO->GPIOio &= ~pLed->ledMaskFail;// turn off the led ++ pLed->ledState = pLed->savedLedState = kLedStateOff; ++ } ++} ++ ++ ++// toggle the led and return the current ledState ++BOARD_LED_STATE ledToggle(PLED_INFO pLed) ++{ ++ GPIO->GPIODir |= pLed->ledMask; // turn on the direction bit in case was turned off by some one ++ if (GPIO->GPIOio & pLed->ledMask) ++ { ++ GPIO->GPIOio &= ~(pLed->ledMask); ++ return( (pLed->ledActiveLow) ? kLedStateOn : kLedStateOff ); ++ } ++ else ++ { ++ GPIO->GPIOio |= pLed->ledMask; ++ return( (pLed->ledActiveLow) ? kLedStateOff : kLedStateOn ); ++ } ++} ++ ++ ++// led timer. Will return if timer is already on ++void ledTimerStart(void) ++{ ++ if (gTimerOn) ++ return; ++ ++#if defined(DEBUG_LED) ++ printk("led: add_timer\n"); ++#endif ++ ++ init_timer(&gLedTimer); ++ gLedTimer.function = (void*)ledTimerExpire; ++ gLedTimer.expires = jiffies + k100ms; // timer expires in ~100ms ++ add_timer (&gLedTimer); ++ gTimerOn = TRUE; ++} ++ ++ ++// led timer expire kicks in about ~100ms and perform the led operation according to the ledState and ++// restart the timer according to ledState ++void ledTimerExpire(void) ++{ ++ int i; ++ PLED_INFO pCurLed; ++ ++ gTimerOn = FALSE; ++ ++ for (i = 0, pCurLed = gLed; i < gLedCount; i++, pCurLed++) ++ { ++#if defined(DEBUG_LED) ++ printk("led[%d]: Mask=0x%04x, State = %d, blcd=%d\n", i, pCurLed->ledMask, pCurLed->ledState, pCurLed->blinkCountDown); ++#endif ++ switch (pCurLed->ledState) ++ { ++ case kLedStateOn: ++ case kLedStateOff: ++ case kLedStateFail: ++ pCurLed->blinkCountDown = 0; // reset the blink count down ++ break; ++ ++ case kLedStateBlinkOnce: ++ ledToggle(pCurLed); ++ pCurLed->blinkCountDown = 0; // reset to 0 ++ pCurLed->ledState = pCurLed->savedLedState; ++ if (pCurLed->ledState == kLedStateSlowBlinkContinues || ++ pCurLed->ledState == kLedStateFastBlinkContinues) ++ ledTimerStart(); // start timer if in blinkContinues stats ++ break; ++ ++ case kLedStateSlowBlinkContinues: ++ if (pCurLed->blinkCountDown-- == 0) ++ { ++ pCurLed->blinkCountDown = kSlowBlinkCount; ++ ledToggle(pCurLed); ++ } ++ ledTimerStart(); ++ break; ++ ++ case kLedStateFastBlinkContinues: ++ if (pCurLed->blinkCountDown-- == 0) ++ { ++ pCurLed->blinkCountDown = kFastBlinkCount; ++ ledToggle(pCurLed); ++ } ++ ledTimerStart(); ++ break; ++ ++ default: ++ printk("Invalid state = %d\n", pCurLed->ledState); ++ } ++ } ++} ++ ++// initialize the gLedCount and allocate and fill gLed struct ++void __init boardLedInit(PLED_MAP_PAIR cLedMapping) ++{ ++ PLED_MAP_PAIR p1, p2; ++ PLED_INFO pCurLed; ++ int needTimer = FALSE; ++ int alreadyUsed = 0; ++ ++#if defined(CONFIG_BCM96348) || defined(CONFIG_BCM96338) ++ /* Set blink rate for BCM6348/BCM6338 hardware LEDs. */ ++ GPIO->LEDCtrl &= ~LED_INTERVAL_SET_MASK; ++ GPIO->LEDCtrl |= LED_INTERVAL_SET_80MS; ++#endif ++ ++ memset( gpVirtLeds, 0x00, sizeof(gpVirtLeds) ); ++ memset( gLedHwFunc, 0x00, sizeof(gLedHwFunc) ); ++ memset( gLedHwFailFunc, 0x00, sizeof(gLedHwFailFunc) ); ++ ++ gLedCount = 0; ++ ++ // Check for multiple LED names and multiple LED GPIO pins that share the ++ // same physical board LED. ++ for( p1 = cLedMapping; p1->ledName != kLedEnd; p1++ ) ++ { ++ alreadyUsed = 0; ++ for( p2 = cLedMapping; p2 != p1; p2++ ) ++ { ++ if( (p1->ledMask && p1->ledMask == p2->ledMask) || ++ (p1->ledMaskFail && p1->ledMaskFail == p2->ledMaskFail) ) ++ { ++ alreadyUsed = 1; ++ break; ++ } ++ } ++ ++ if( alreadyUsed == 0 ) ++ gLedCount++; ++ } ++ ++ gLed = (PLED_INFO) kmalloc((gLedCount * sizeof(LED_INFO)), GFP_KERNEL); ++ if( gLed == NULL ) ++ { ++ printk( "LED memory allocation error.\n" ); ++ return; ++ } ++ ++ memset( gLed, 0x00, gLedCount * sizeof(LED_INFO) ); ++ ++ // initial the gLed with unique ledMask and initial state. If more than 1 ledNames share the physical led ++ // (ledMask) the first defined led's ledInitState will be used. ++ pCurLed = gLed; ++ for( p1 = cLedMapping; p1->ledName != kLedEnd; p1++ ) ++ { ++ if( (int) p1->ledName > MAX_VIRT_LEDS ) ++ continue; ++ ++ alreadyUsed = 0; ++ for( p2 = cLedMapping; p2 != p1; p2++ ) ++ { ++ if( (p1->ledMask && p1->ledMask == p2->ledMask) || ++ (p1->ledMaskFail && p1->ledMaskFail == p2->ledMaskFail) ) ++ { ++ alreadyUsed = 1; ++ break; ++ } ++ } ++ ++ if( alreadyUsed == 0 ) ++ { ++ // Initialize the board LED for the first time. ++ needTimer = initLedInfo( p1, pCurLed ); ++ gpVirtLeds[(int) p1->ledName] = pCurLed; ++ pCurLed++; ++ } ++ else ++ { ++ PLED_INFO pLed; ++ for( pLed = gLed; pLed != pCurLed; pLed++ ) ++ { ++ // Find the LED_INFO structure that has already been initialized. ++ if((pLed->ledMask && pLed->ledMask == p1->ledMask) || ++ (pLed->ledMaskFail && pLed->ledMaskFail==p1->ledMaskFail)) ++ { ++ // The board LED has already been initialized but possibly ++ // not completely initialized. ++ if( p1->ledMask ) ++ { ++ pLed->ledMask = p1->ledMask; ++ pLed->ledActiveLow = p1->ledActiveLow; ++ } ++ if( p1->ledMaskFail ) ++ { ++ pLed->ledMaskFail = p1->ledMaskFail; ++ pLed->ledActiveLowFail = p1->ledActiveLowFail; ++ } ++ gpVirtLeds[(int) p1->ledName] = pLed; ++ break; ++ } ++ } ++ } ++ } ++ ++ if (needTimer) ++ ledTimerStart(); ++ ++#if defined(DEBUG_LED) ++ int i; ++ for (i=0; i < gLedCount; i++) ++ printk("initLed: led[%d]: mask=0x%04x, state=%d\n", i,(gLed+i)->ledMask, (gLed+i)->ledState); ++#endif ++ ++} ++ ++// Initialize a structure that contains information about a physical board LED ++// control. The board LED may contain more than one GPIO pin to control a ++// normal condition (green) or a failure condition (red). ++int initLedInfo( PLED_MAP_PAIR pCurMap, PLED_INFO pCurLed ) ++{ ++ int needTimer = FALSE; ++ pCurLed->ledState = pCurLed->savedLedState = pCurMap->ledInitState; ++ pCurLed->ledMask = pCurMap->ledMask; ++ pCurLed->ledActiveLow = pCurMap->ledActiveLow; ++ pCurLed->ledMaskFail = pCurMap->ledMaskFail; ++ pCurLed->ledActiveLowFail = pCurMap->ledActiveLowFail; ++ ++ switch (pCurLed->ledState) ++ { ++ case kLedStateOn: ++ pCurLed->blinkCountDown = 0; // reset the blink count down ++ ledOn(pCurLed); ++ break; ++ case kLedStateOff: ++ pCurLed->blinkCountDown = 0; // reset the blink count down ++ ledOff(pCurLed); ++ break; ++ case kLedStateFail: ++ pCurLed->blinkCountDown = 0; // reset the blink count down ++ ledOnFail(pCurLed); ++ break; ++ case kLedStateBlinkOnce: ++ pCurLed->blinkCountDown = 1; ++ needTimer = TRUE; ++ break; ++ case kLedStateSlowBlinkContinues: ++ pCurLed->blinkCountDown = kSlowBlinkCount; ++ needTimer = TRUE; ++ break; ++ case kLedStateFastBlinkContinues: ++ pCurLed->blinkCountDown = kFastBlinkCount; ++ needTimer = TRUE; ++ break; ++ default: ++ printk("Invalid state = %d\n", pCurLed->ledState); ++ } ++ ++ return( needTimer ); ++} ++ ++#if 0 /* BROKEN */ ++// Determines if there is at least one interface in bridge mode. Bridge mode ++// is determined by the cfm convention of naming bridge interfaces nas17 ++// through nas24. ++static int isBridgedProtocol(void) ++{ ++ extern int dev_get(const char *name); ++ const int firstBridgeId = 17; ++ const int lastBridgeId = 24; ++ int i; ++ int ret = FALSE; ++ char name[16]; ++ ++ for( i = firstBridgeId; i <= lastBridgeId; i++ ) ++ { ++ sprintf( name, "nas%d", i ); ++ ++ if( dev_get(name) ) ++ { ++ ret = TRUE; ++ break; ++ } ++ } ++ ++ return(ret); ++} ++#endif ++ ++// led ctrl. Maps the ledName to the corresponding ledInfoPtr and perform the led operation ++void boardLedCtrl(BOARD_LED_NAME ledName, BOARD_LED_STATE ledState) ++{ ++ PLED_INFO ledInfoPtr; ++ ++ // do the mapping from virtual to physical led ++ if( (int) ledName < MAX_VIRT_LEDS ) ++ ledInfoPtr = gpVirtLeds[(int) ledName]; ++ else ++ ledInfoPtr = NULL; ++ ++ if (ledInfoPtr == NULL) ++ return; ++ ++ if( ledState != kLedStateFail && gLedHwFunc[(int) ledName] ) ++ { ++ (*gLedHwFunc[(int) ledName]) (ledName, ledState); ++ ledOffFail(ledInfoPtr); ++ return; ++ } ++ else ++ if( ledState == kLedStateFail && gLedHwFailFunc[(int) ledName] ) ++ { ++ (*gLedHwFailFunc[(int) ledName]) (ledName, ledState); ++ ledOff(ledInfoPtr); ++ return; ++ } ++ ++#if 0 /* BROKEN */ ++ // Do not blink the WAN Data LED if at least one interface is in bridge mode. ++ if(gLedOffInBridgeMode == 1 && (ledName == kLedWanData || ledName == kLedPPP)) ++ { ++ static int BridgedProtocol = -1; ++ ++ if( BridgedProtocol == -1 ) ++ BridgedProtocol = isBridgedProtocol(); ++ ++ if( BridgedProtocol == TRUE ) ++ return; ++ } ++#endif ++ ++ // If the state is kLedStateFail and there is not a failure LED defined ++ // in the board parameters, change the state to kLedStateFastBlinkContinues. ++ if( ledState == kLedStateFail && ledInfoPtr->ledMaskFail == 0 ) ++ ledState = kLedStateFastBlinkContinues; ++ ++ switch (ledState) ++ { ++ case kLedStateOn: ++ // First, turn off the complimentary (failure) LED GPIO. ++ if( ledInfoPtr->ledMaskFail ) ++ ledOffFail(ledInfoPtr); ++ else ++ if( gLedHwFailFunc[(int) ledName] ) ++ (*gLedHwFailFunc[(int) ledName]) (ledName, kLedStateOff); ++ ++ // Next, turn on the specified LED GPIO. ++ ledOn(ledInfoPtr); ++ break; ++ ++ case kLedStateOff: ++ // First, turn off the complimentary (failure) LED GPIO. ++ if( ledInfoPtr->ledMaskFail ) ++ ledOffFail(ledInfoPtr); ++ else ++ if( gLedHwFailFunc[(int) ledName] ) ++ (*gLedHwFailFunc[(int) ledName]) (ledName, kLedStateOff); ++ ++ // Next, turn off the specified LED GPIO. ++ ledOff(ledInfoPtr); ++ break; ++ ++ case kLedStateFail: ++ // First, turn off the complimentary (normal) LED GPIO. ++ if( ledInfoPtr->ledMask ) ++ ledOff(ledInfoPtr); ++ else ++ if( gLedHwFunc[(int) ledName] ) ++ (*gLedHwFunc[(int) ledName]) (ledName, kLedStateOff); ++ ++ // Next, turn on (red) the specified LED GPIO. ++ ledOnFail(ledInfoPtr); ++ break; ++ ++ case kLedStateBlinkOnce: ++ // skip blinkOnce if it is already in Slow/Fast blink continues state ++ if (ledInfoPtr->savedLedState == kLedStateSlowBlinkContinues || ++ ledInfoPtr->savedLedState == kLedStateFastBlinkContinues) ++ ; ++ else ++ { ++ if (ledInfoPtr->blinkCountDown == 0) // skip the call if it is 1 ++ { ++ ledToggle(ledInfoPtr); ++ ledInfoPtr->blinkCountDown = 1; // it will be reset to 0 when timer expires ++ ledInfoPtr->ledState = kLedStateBlinkOnce; ++ ledTimerStart(); ++ } ++ } ++ break; ++ ++ case kLedStateSlowBlinkContinues: ++ ledInfoPtr->blinkCountDown = kSlowBlinkCount; ++ ledInfoPtr->ledState = kLedStateSlowBlinkContinues; ++ ledInfoPtr->savedLedState = kLedStateSlowBlinkContinues; ++ ledTimerStart(); ++ break; ++ ++ case kLedStateFastBlinkContinues: ++ ledInfoPtr->blinkCountDown = kFastBlinkCount; ++ ledInfoPtr->ledState = kLedStateFastBlinkContinues; ++ ledInfoPtr->savedLedState = kLedStateFastBlinkContinues; ++ ledTimerStart(); ++ break; ++ ++ default: ++ printk("Invalid led state\n"); ++ } ++} ++ ++// This function is called for an LED that is controlled by hardware. ++void kerSysLedRegisterHwHandler( BOARD_LED_NAME ledName, ++ HANDLE_LED_FUNC ledHwFunc, int ledFailType ) ++{ ++ if( (int) ledName < MAX_VIRT_LEDS ) ++ { ++ if( ledFailType == 1 ) ++ gLedHwFailFunc[(int) ledName] = ledHwFunc; ++ else ++ gLedHwFunc[(int) ledName] = ledHwFunc; ++ } ++} ++ +diff -urN linux-2.6.17/arch/mips/brcm-boards/bcm963xx/board.c linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/board.c +--- linux-2.6.17/arch/mips/brcm-boards/bcm963xx/board.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/board.c 2006-08-03 16:37:21.000000000 +0200 +@@ -0,0 +1,1781 @@ ++/* ++<:copyright-gpl ++ Copyright 2002 Broadcom Corp. All Rights Reserved. ++ ++ This program is free software; you can distribute it and/or modify it ++ under the terms of the GNU General Public License (Version 2) as ++ published by the Free Software Foundation. ++ ++ This program is distributed in the hope it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++:> ++*/ ++/*************************************************************************** ++ * File Name : board.c ++ * ++ * Description: This file contains Linux character device driver entry ++ * for the board related ioctl calls: flash, get free kernel ++ * page and dump kernel memory, etc. ++ * ++ * Created on : 2/20/2002 seanl: use cfiflash.c, cfliflash.h (AMD specific) ++ * ++ ***************************************************************************/ ++ ++ ++/* Includes. */ ++#include <linux/version.h> ++#include <linux/init.h> ++#include <linux/fs.h> ++#include <linux/interrupt.h> ++#include <linux/capability.h> ++#include <linux/slab.h> ++#include <linux/errno.h> ++#include <linux/module.h> ++#include <linux/pagemap.h> ++#include <asm/uaccess.h> ++#include <linux/wait.h> ++#include <linux/poll.h> ++#include <linux/sched.h> ++#include <linux/list.h> ++#include <linux/if.h> ++#include <linux/spinlock.h> ++ ++#include <bcm_map_part.h> ++#include <board.h> ++#include <bcmTag.h> ++#include "boardparms.h" ++#include "cfiflash.h" ++#include "bcm_intr.h" ++#include "board.h" ++#include "bcm_map_part.h" ++ ++static DEFINE_SPINLOCK(board_lock); ++ ++/* Typedefs. */ ++#if defined (NON_CONSECUTIVE_MAC) ++// used to be the last octet. Now changed to the first 5 bits of the the forth octet ++// to reduced the duplicated MAC addresses. ++#define CHANGED_OCTET 3 ++#define SHIFT_BITS 3 ++#else ++#define CHANGED_OCTET 1 ++#define SHIFT_BITS 0 ++#endif ++ ++#if defined (WIRELESS) ++#define SES_BTN_PRESSED 0x00000001 ++#define SES_EVENTS SES_BTN_PRESSED /*OR all values if any*/ ++#define SES_LED_OFF 0 ++#define SES_LED_ON 1 ++#define SES_LED_BLINK 2 ++#endif ++ ++typedef struct ++{ ++ unsigned long ulId; ++ char chInUse; ++ char chReserved[3]; ++} MAC_ADDR_INFO, *PMAC_ADDR_INFO; ++ ++typedef struct ++{ ++ unsigned long ulSdramSize; ++ unsigned long ulPsiSize; ++ unsigned long ulNumMacAddrs; ++ unsigned long ucaBaseMacAddr[NVRAM_MAC_ADDRESS_LEN]; ++ MAC_ADDR_INFO MacAddrs[1]; ++} NVRAM_INFO, *PNVRAM_INFO; ++ ++typedef struct ++{ ++ unsigned long eventmask; ++} BOARD_IOC, *PBOARD_IOC; ++ ++ ++/*Dyinggasp callback*/ ++typedef void (*cb_dgasp_t)(void *arg); ++typedef struct _CB_DGASP__LIST ++{ ++ struct list_head list; ++ char name[IFNAMSIZ]; ++ cb_dgasp_t cb_dgasp_fn; ++ void *context; ++}CB_DGASP_LIST , *PCB_DGASP_LIST; ++ ++ ++static LED_MAP_PAIR LedMapping[] = ++{ // led name Initial state physical pin (ledMask) ++ {kLedEnd, kLedStateOff, 0, 0, 0, 0}, ++ {kLedEnd, kLedStateOff, 0, 0, 0, 0}, ++ {kLedEnd, kLedStateOff, 0, 0, 0, 0}, ++ {kLedEnd, kLedStateOff, 0, 0, 0, 0}, ++ {kLedEnd, kLedStateOff, 0, 0, 0, 0}, ++ {kLedEnd, kLedStateOff, 0, 0, 0, 0}, ++ {kLedEnd, kLedStateOff, 0, 0, 0, 0}, ++ {kLedEnd, kLedStateOff, 0, 0, 0, 0}, ++ {kLedEnd, kLedStateOff, 0, 0, 0, 0} // NOTE: kLedEnd has to be at the end. ++}; ++ ++/* Externs. */ ++extern struct file fastcall *fget_light(unsigned int fd, int *fput_needed); ++extern unsigned int nr_free_pages (void); ++extern const char *get_system_type(void); ++extern void kerSysFlashInit(void); ++extern unsigned long get_nvram_start_addr(void); ++extern unsigned long get_scratch_pad_start_addr(void); ++extern unsigned long getMemorySize(void); ++extern void __init boardLedInit(PLED_MAP_PAIR); ++extern void boardLedCtrl(BOARD_LED_NAME, BOARD_LED_STATE); ++extern void kerSysLedRegisterHandler( BOARD_LED_NAME ledName, ++ HANDLE_LED_FUNC ledHwFunc, int ledFailType ); ++ ++/* Prototypes. */ ++void __init InitNvramInfo( void ); ++static int board_open( struct inode *inode, struct file *filp ); ++static int board_ioctl( struct inode *inode, struct file *flip, unsigned int command, unsigned long arg ); ++static ssize_t board_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos); ++static unsigned int board_poll(struct file *filp, struct poll_table_struct *wait); ++static int board_release(struct inode *inode, struct file *filp); ++ ++static BOARD_IOC* borad_ioc_alloc(void); ++static void borad_ioc_free(BOARD_IOC* board_ioc); ++ ++/* DyingGasp function prototype */ ++static void __init kerSysDyingGaspMapIntr(void); ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) ++static irqreturn_t kerSysDyingGaspIsr(int irq, void * dev_id, struct pt_regs * regs); ++#else ++static unsigned int kerSysDyingGaspIsr(void); ++#endif ++static void __init kerSysInitDyingGaspHandler( void ); ++static void __exit kerSysDeinitDyingGaspHandler( void ); ++/* -DyingGasp function prototype - */ ++ ++ ++#if defined (WIRELESS) ++static irqreturn_t sesBtn_isr(int irq, void *dev_id, struct pt_regs *ptregs); ++static void __init sesBtn_mapGpio(void); ++static void __init sesBtn_mapIntr(int context); ++static unsigned int sesBtn_poll(struct file *file, struct poll_table_struct *wait); ++static ssize_t sesBtn_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos); ++static void __init sesLed_mapGpio(void); ++static void sesLed_ctrl(int action); ++static void __init ses_board_init(void); ++static void __exit ses_board_deinit(void); ++#endif ++ ++static PNVRAM_INFO g_pNvramInfo = NULL; ++static int g_ledInitialized = 0; ++static wait_queue_head_t g_board_wait_queue; ++static CB_DGASP_LIST *g_cb_dgasp_list_head = NULL; ++ ++static int g_wakeup_monitor = 0; ++static struct file *g_monitor_file = NULL; ++static struct task_struct *g_monitor_task = NULL; ++static unsigned int (*g_orig_fop_poll) ++ (struct file *, struct poll_table_struct *) = NULL; ++ ++static struct file_operations board_fops = ++{ ++ open: board_open, ++ ioctl: board_ioctl, ++ poll: board_poll, ++ read: board_read, ++ release: board_release, ++}; ++ ++uint32 board_major = 0; ++ ++#if defined (WIRELESS) ++static unsigned short sesBtn_irq = BP_NOT_DEFINED; ++static unsigned short sesBtn_gpio = BP_NOT_DEFINED; ++static unsigned short sesLed_gpio = BP_NOT_DEFINED; ++#endif ++ ++#if defined(MODULE) ++int init_module(void) ++{ ++ return( brcm_board_init() ); ++} ++ ++void cleanup_module(void) ++{ ++ if (MOD_IN_USE) ++ printk("brcm flash: cleanup_module failed because module is in use\n"); ++ else ++ brcm_board_cleanup(); ++} ++#endif //MODULE ++ ++ ++ ++static int __init brcm_board_init( void ) ++{ ++ typedef int (*BP_LED_FUNC) (unsigned short *); ++ static struct BpLedInformation ++ { ++ BOARD_LED_NAME ledName; ++ BP_LED_FUNC bpFunc; ++ BP_LED_FUNC bpFuncFail; ++ } bpLedInfo[] = ++ {{kLedAdsl, BpGetAdslLedGpio, BpGetAdslFailLedGpio}, ++ {kLedWireless, BpGetWirelessLedGpio, NULL}, ++ {kLedUsb, BpGetUsbLedGpio, NULL}, ++ {kLedHpna, BpGetHpnaLedGpio, NULL}, ++ {kLedWanData, BpGetWanDataLedGpio, NULL}, ++ {kLedPPP, BpGetPppLedGpio, BpGetPppFailLedGpio}, ++ {kLedVoip, BpGetVoipLedGpio, NULL}, ++ {kLedSes, BpGetWirelessSesLedGpio, NULL}, ++ {kLedEnd, NULL, NULL} ++ }; ++ ++ int ret; ++ ++ ret = register_chrdev(BOARD_DRV_MAJOR, "bcrmboard", &board_fops ); ++ if (ret < 0) ++ printk( "brcm_board_init(major %d): fail to register device.\n",BOARD_DRV_MAJOR); ++ else ++ { ++ PLED_MAP_PAIR pLedMap = LedMapping; ++ unsigned short gpio; ++ struct BpLedInformation *pInfo; ++ ++ printk("brcmboard: brcm_board_init entry\n"); ++ board_major = BOARD_DRV_MAJOR; + if (boot_loader_type == BOOT_CFE) ++ InitNvramInfo(); ++ ++#if !defined(CONFIG_BCM96338) ++ GPIO->GPIOMode &= ~(0x000F0000); ++#endif ++ ++ pLedMap[0].ledName = kLedSelfTest ; ++ pLedMap[0].ledMask = GPIO_NUM_TO_MASK(0); ++ pLedMap[0].ledActiveLow = 0; ++ ++ pLedMap[1].ledName = kLedAdsl; ++ pLedMap[1].ledMask = GPIO_NUM_TO_MASK(1); ++ pLedMap[1].ledActiveLow = 0; ++ ++ pLedMap[2].ledName = kLedLan ; ++ pLedMap[2].ledMask = GPIO_NUM_TO_MASK(2); ++ pLedMap[2].ledActiveLow = 0; ++ ++ pLedMap[3].ledName = kLedVoip ; ++ pLedMap[3].ledMask = GPIO_NUM_TO_MASK(3); ++ pLedMap[3].ledActiveLow = 0; ++ ++ pLedMap[4].ledName = kLedWireless ; ++ pLedMap[4].ledMask = GPIO_NUM_TO_MASK(4); ++ pLedMap[4].ledActiveLow = 0; ++ ++ pLedMap[5].ledName = kLedEnd; ++ ++#if 0 ++ for( pInfo = bpLedInfo; pInfo->ledName != kLedEnd; pInfo++ ) ++ { ++ if( pInfo->bpFunc && (*pInfo->bpFunc) (&gpio) == BP_SUCCESS ) ++ { ++ pLedMap->ledName = pInfo->ledName; ++ pLedMap->ledMask = GPIO_NUM_TO_MASK(gpio); ++ pLedMap->ledActiveLow = (gpio & BP_ACTIVE_LOW) ? 1 : 0; ++ } ++ if( pInfo->bpFuncFail && (*pInfo->bpFuncFail) (&gpio) == BP_SUCCESS ) ++ { ++ pLedMap->ledName = pInfo->ledName; ++ pLedMap->ledMaskFail = GPIO_NUM_TO_MASK(gpio); ++ pLedMap->ledActiveLowFail = (gpio & BP_ACTIVE_LOW) ? 1 : 0; ++ } ++ if( pLedMap->ledName != kLedEnd ) ++ pLedMap++; ++ } ++#endif ++ init_waitqueue_head(&g_board_wait_queue); ++#if defined (WIRELESS) ++ ses_board_init(); ++#endif ++ kerSysInitDyingGaspHandler(); ++ kerSysDyingGaspMapIntr(); ++ ++ boardLedInit(LedMapping); ++ g_ledInitialized = 1; ++ } ++ ++ return ret; ++} ++ ++void __init InitNvramInfo( void ) ++{ ++ PNVRAM_DATA pNvramData = (PNVRAM_DATA) get_nvram_start_addr(); ++ unsigned long ulNumMacAddrs = pNvramData->ulNumMacAddrs; ++ ++ if( ulNumMacAddrs > 0 && ulNumMacAddrs <= NVRAM_MAC_COUNT_MAX ) ++ { ++ unsigned long ulNvramInfoSize = ++ sizeof(NVRAM_INFO) + ((sizeof(MAC_ADDR_INFO) - 1) * ulNumMacAddrs); ++ ++ g_pNvramInfo = (PNVRAM_INFO) kmalloc( ulNvramInfoSize, GFP_KERNEL ); ++ ++ if( g_pNvramInfo ) ++ { ++ unsigned long ulPsiSize; ++ if( BpGetPsiSize( &ulPsiSize ) != BP_SUCCESS ) ++ ulPsiSize = NVRAM_PSI_DEFAULT; ++ memset( g_pNvramInfo, 0x00, ulNvramInfoSize ); ++ g_pNvramInfo->ulPsiSize = ulPsiSize * 1024; ++ g_pNvramInfo->ulNumMacAddrs = pNvramData->ulNumMacAddrs; ++ memcpy( g_pNvramInfo->ucaBaseMacAddr, pNvramData->ucaBaseMacAddr, ++ NVRAM_MAC_ADDRESS_LEN ); ++ g_pNvramInfo->ulSdramSize = getMemorySize(); ++ } ++ else ++ printk("ERROR - Could not allocate memory for NVRAM data\n"); ++ } ++ else ++ printk("ERROR - Invalid number of MAC addresses (%ld) is configured.\n", ++ ulNumMacAddrs); ++} ++ ++void __exit brcm_board_cleanup( void ) ++{ ++ printk("brcm_board_cleanup()\n"); ++ ++ if (board_major != -1) ++ { ++#if defined (WIRELESS) ++ ses_board_deinit(); ++#endif ++ kerSysDeinitDyingGaspHandler(); ++ unregister_chrdev(board_major, "board_ioctl"); ++ } ++} ++ ++static BOARD_IOC* borad_ioc_alloc(void) ++{ ++ BOARD_IOC *board_ioc =NULL; ++ board_ioc = (BOARD_IOC*) kmalloc( sizeof(BOARD_IOC) , GFP_KERNEL ); ++ if(board_ioc) ++ { ++ memset(board_ioc, 0, sizeof(BOARD_IOC)); ++ } ++ return board_ioc; ++} ++ ++static void borad_ioc_free(BOARD_IOC* board_ioc) ++{ ++ if(board_ioc) ++ { ++ kfree(board_ioc); ++ } ++} ++ ++ ++static int board_open( struct inode *inode, struct file *filp ) ++{ ++ filp->private_data = borad_ioc_alloc(); ++ ++ if (filp->private_data == NULL) ++ return -ENOMEM; ++ ++ return( 0 ); ++} ++ ++static int board_release(struct inode *inode, struct file *filp) ++{ ++ BOARD_IOC *board_ioc = filp->private_data; ++ ++ wait_event_interruptible(g_board_wait_queue, 1); ++ borad_ioc_free(board_ioc); ++ ++ return( 0 ); ++} ++ ++ ++static unsigned int board_poll(struct file *filp, struct poll_table_struct *wait) ++{ ++ unsigned int mask = 0; ++#if defined (WIRELESS) ++ BOARD_IOC *board_ioc = filp->private_data; ++#endif ++ ++ poll_wait(filp, &g_board_wait_queue, wait); ++#if defined (WIRELESS) ++ if(board_ioc->eventmask & SES_EVENTS){ ++ mask |= sesBtn_poll(filp, wait); ++ } ++#endif ++ ++ return mask; ++} ++ ++ ++static ssize_t board_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos) ++{ ++#if defined (WIRELESS) ++ BOARD_IOC *board_ioc = filp->private_data; ++ if(board_ioc->eventmask & SES_EVENTS){ ++ return sesBtn_read(filp, buffer, count, ppos); ++ } ++#endif ++ return 0; ++} ++ ++//************************************************************************************** ++// Utitlities for dump memory, free kernel pages, mips soft reset, etc. ++//************************************************************************************** ++ ++/*********************************************************************** ++ * Function Name: dumpaddr ++ * Description : Display a hex dump of the specified address. ++ ***********************************************************************/ ++void dumpaddr( unsigned char *pAddr, int nLen ) ++{ ++ static char szHexChars[] = "0123456789abcdef"; ++ char szLine[80]; ++ char *p = szLine; ++ unsigned char ch, *q; ++ int i, j; ++ unsigned long ul; ++ ++ while( nLen > 0 ) ++ { ++ sprintf( szLine, "%8.8lx: ", (unsigned long) pAddr ); ++ p = szLine + strlen(szLine); ++ ++ for(i = 0; i < 16 && nLen > 0; i += sizeof(long), nLen -= sizeof(long)) ++ { ++ ul = *(unsigned long *) &pAddr[i]; ++ q = (unsigned char *) &ul; ++ for( j = 0; j < sizeof(long); j++ ) ++ { ++ *p++ = szHexChars[q[j] >> 4]; ++ *p++ = szHexChars[q[j] & 0x0f]; ++ *p++ = ' '; ++ } ++ } ++ ++ for( j = 0; j < 16 - i; j++ ) ++ *p++ = ' ', *p++ = ' ', *p++ = ' '; ++ ++ *p++ = ' ', *p++ = ' ', *p++ = ' '; ++ ++ for( j = 0; j < i; j++ ) ++ { ++ ch = pAddr[j]; ++ *p++ = (ch > ' ' && ch < '~') ? ch : '.'; ++ } ++ ++ *p++ = '\0'; ++ printk( "%s\r\n", szLine ); ++ ++ pAddr += i; ++ } ++ printk( "\r\n" ); ++} /* dumpaddr */ ++ ++ ++void kerSysMipsSoftReset(void) ++{ ++#if defined(CONFIG_BCM96348) ++ if (PERF->RevID == 0x634800A1) { ++ typedef void (*FNPTR) (void); ++ FNPTR bootaddr = (FNPTR) FLASH_BASE; ++ int i; ++ ++ /* Disable interrupts. */ ++ //cli(); ++ spin_lock_irq(&board_lock); ++ ++ /* Reset all blocks. */ ++ PERF->BlockSoftReset &= ~BSR_ALL_BLOCKS; ++ for( i = 0; i < 1000000; i++ ) ++ ; ++ PERF->BlockSoftReset |= BSR_ALL_BLOCKS; ++ /* Jump to the power on address. */ ++ (*bootaddr) (); ++ } ++ else ++ PERF->pll_control |= SOFT_RESET; // soft reset mips ++#else ++ PERF->pll_control |= SOFT_RESET; // soft reset mips ++#endif ++} ++ ++ ++int kerSysGetMacAddress( unsigned char *pucaMacAddr, unsigned long ulId ) ++{ ++ int nRet = 0; ++ PMAC_ADDR_INFO pMai = NULL; ++ PMAC_ADDR_INFO pMaiFreeNoId = NULL; ++ PMAC_ADDR_INFO pMaiFreeId = NULL; ++ unsigned long i = 0, ulIdxNoId = 0, ulIdxId = 0, shiftedIdx = 0; ++ ++ /* CMO -- Fix le problème avec les adresses mac que l'on n'arrive pas ++ * * à relire plusieurs fois */ ++ /* inv_xde */ + if (boot_loader_type == BOOT_CFE) ++ memcpy( pucaMacAddr, g_pNvramInfo->ucaBaseMacAddr, ++ NVRAM_MAC_ADDRESS_LEN ); ++ else { ++ pucaMacAddr[0] = 0x00; ++ pucaMacAddr[1] = 0x07; ++ pucaMacAddr[2] = 0x3A; ++ pucaMacAddr[3] = 0xFF; ++ pucaMacAddr[4] = 0xFF; ++ pucaMacAddr[5] = 0xFF; ++ } ++ ++ return nRet; ++#if 0 ++ for( i = 0, pMai = g_pNvramInfo->MacAddrs; i < g_pNvramInfo->ulNumMacAddrs; ++ i++, pMai++ ) ++ { ++ if( ulId == pMai->ulId || ulId == MAC_ADDRESS_ANY ) ++ { ++ /* This MAC address has been used by the caller in the past. */ ++ memcpy( pucaMacAddr, g_pNvramInfo->ucaBaseMacAddr, ++ NVRAM_MAC_ADDRESS_LEN ); ++ shiftedIdx = i; ++ pucaMacAddr[NVRAM_MAC_ADDRESS_LEN - CHANGED_OCTET] += (shiftedIdx << SHIFT_BITS); ++ pMai->chInUse = 1; ++ pMaiFreeNoId = pMaiFreeId = NULL; ++ break; ++ } ++ else ++ if( pMai->chInUse == 0 ) ++ { ++ if( pMai->ulId == 0 && pMaiFreeNoId == NULL ) ++ { ++ /* This is an available MAC address that has never been ++ * used. ++ */ ++ pMaiFreeNoId = pMai; ++ ulIdxNoId = i; ++ } ++ else ++ if( pMai->ulId != 0 && pMaiFreeId == NULL ) ++ { ++ /* This is an available MAC address that has been used ++ * before. Use addresses that have never been used ++ * first, before using this one. ++ */ ++ pMaiFreeId = pMai; ++ ulIdxId = i; ++ } ++ } ++ } ++ ++ if( pMaiFreeNoId || pMaiFreeId ) ++ { ++ /* An available MAC address was found. */ ++ memcpy(pucaMacAddr, g_pNvramInfo->ucaBaseMacAddr,NVRAM_MAC_ADDRESS_LEN); ++ if( pMaiFreeNoId ) ++ { ++ shiftedIdx = ulIdxNoId; ++ pucaMacAddr[NVRAM_MAC_ADDRESS_LEN - CHANGED_OCTET] += (shiftedIdx << SHIFT_BITS); ++ pMaiFreeNoId->ulId = ulId; ++ pMaiFreeNoId->chInUse = 1; ++ } ++ else ++ { ++ shiftedIdx = ulIdxId; ++ pucaMacAddr[NVRAM_MAC_ADDRESS_LEN - CHANGED_OCTET] += (shiftedIdx << SHIFT_BITS); ++ pMaiFreeId->ulId = ulId; ++ pMaiFreeId->chInUse = 1; ++ } ++ } ++ else ++ if( i == g_pNvramInfo->ulNumMacAddrs ) ++ nRet = -EADDRNOTAVAIL; ++ ++ return( nRet ); ++#endif ++} /* kerSysGetMacAddr */ ++ ++int kerSysReleaseMacAddress( unsigned char *pucaMacAddr ) ++{ ++ int nRet = -EINVAL; ++ unsigned long ulIdx = 0; ++ int idx = (pucaMacAddr[NVRAM_MAC_ADDRESS_LEN - CHANGED_OCTET] - ++ g_pNvramInfo->ucaBaseMacAddr[NVRAM_MAC_ADDRESS_LEN - CHANGED_OCTET]); ++ ++ // if overflow 255 (negitive), add 256 to have the correct index ++ if (idx < 0) ++ idx += 256; ++ ulIdx = (unsigned long) (idx >> SHIFT_BITS); ++ ++ if( ulIdx < g_pNvramInfo->ulNumMacAddrs ) ++ { ++ PMAC_ADDR_INFO pMai = &g_pNvramInfo->MacAddrs[ulIdx]; ++ if( pMai->chInUse == 1 ) ++ { ++ pMai->chInUse = 0; ++ nRet = 0; ++ } ++ } ++ ++ return( nRet ); ++} /* kerSysReleaseMacAddr */ ++ ++int kerSysGetSdramSize( void ) ++{ + if (boot_loader_type == BOOT_CFE) { ++ return( (int) g_pNvramInfo->ulSdramSize ); ++ } ++ else { ++ printk("kerSysGetSdramSize : 0x%08X\n", (int)getMemorySize() + 0x00040000); ++ return((int)getMemorySize() + 0x00040000); ++ } ++} /* kerSysGetSdramSize */ ++ ++ ++void kerSysLedCtrl(BOARD_LED_NAME ledName, BOARD_LED_STATE ledState) ++{ ++ if (g_ledInitialized) ++ boardLedCtrl(ledName, ledState); ++} ++ ++unsigned int kerSysMonitorPollHook( struct file *f, struct poll_table_struct *t) ++{ ++ int mask = (*g_orig_fop_poll) (f, t); ++ ++ if( g_wakeup_monitor == 1 && g_monitor_file == f ) ++ { ++ /* If g_wakeup_monitor is non-0, the user mode application needs to ++ * return from a blocking select function. Return POLLPRI which will ++ * cause the select to return with the exception descriptor set. ++ */ ++ mask |= POLLPRI; ++ g_wakeup_monitor = 0; ++ } ++ ++ return( mask ); ++} ++ ++/* Put the user mode application that monitors link state on a run queue. */ ++void kerSysWakeupMonitorTask( void ) ++{ ++ g_wakeup_monitor = 1; ++ if( g_monitor_task ) ++ wake_up_process( g_monitor_task ); ++} ++ ++//<<JUNHON, 2004/09/15, get reset button status , tim hou , 05/04/12 ++int kerSysGetResetHold(void) ++{ ++ unsigned short gpio; ++ ++ if( BpGetPressAndHoldResetGpio( &gpio ) == BP_SUCCESS ) ++ { ++#if defined(CONFIG_BCM96338) ++ unsigned long gpio_mask = GPIO_NUM_TO_MASK(gpio); ++ volatile unsigned long *gpio_reg = &GPIO->GPIOio; ++#endif ++#if defined(CONFIG_BCM96345) ++ unsigned short gpio_mask = GPIO_NUM_TO_MASK(gpio); ++ volatile unsigned short *gpio_reg = &GPIO->GPIOio; ++#endif ++#if defined(CONFIG_BCM96348) ++ unsigned long gpio_mask = GPIO_NUM_TO_MASK(gpio); ++ volatile unsigned long *gpio_reg = &GPIO->GPIOio; ++ ++ if( (gpio & ~BP_ACTIVE_MASK) >= 32 ) ++ { ++ gpio_mask = GPIO_NUM_TO_MASK_HIGH(gpio); ++ gpio_reg = &GPIO->GPIOio_high; ++ } ++#endif ++ //printk("gpio=%04x,gpio_mask=%04x,gpio_reg=%04x\n",gpio,gpio_mask,*gpio_reg); ++ if(*gpio_reg & gpio_mask) //press down ++ return RESET_BUTTON_UP; ++ } ++ return RESET_BUTTON_PRESSDOWN; ++} ++//<<JUNHON, 2004/09/15 ++ ++//******************************************************************************************** ++// misc. ioctl calls come to here. (flash, led, reset, kernel memory access, etc.) ++//******************************************************************************************** ++static int board_ioctl( struct inode *inode, struct file *flip, ++ unsigned int command, unsigned long arg ) ++{ ++ int ret = 0; ++ BOARD_IOCTL_PARMS ctrlParms; ++ unsigned char ucaMacAddr[NVRAM_MAC_ADDRESS_LEN]; ++ int allowedSize; ++ ++ switch (command) ++ { ++ case BOARD_IOCTL_FLASH_INIT: ++ // not used for now. kerSysBcmImageInit(); ++ break; ++ ++ ++ case BOARD_IOCTL_FLASH_WRITE: ++ if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) ++ { ++ NVRAM_DATA SaveNvramData; ++ PNVRAM_DATA pNvramData = (PNVRAM_DATA) get_nvram_start_addr(); ++ ++ switch (ctrlParms.action) ++ { ++ case SCRATCH_PAD: + if (boot_loader_type == BOOT_CFE) { ++ ret = kerSysScratchPadSet(ctrlParms.string, ctrlParms.buf, ctrlParms.offset); ++ } ++ else { ++ printk("RedBoot : not supported\n"); ++ return(-EINVAL); ++ } ++ break; ++ ++ case PERSISTENT: + if (boot_loader_type == BOOT_CFE) { ++ ret = kerSysPersistentSet(ctrlParms.string, ctrlParms.strLen, ctrlParms.offset); ++ } ++ else { ++ printk("RedBoot : not supported\n"); ++ return(-EINVAL); ++ } ++ break; ++ ++ case NVRAM: + if (boot_loader_type == BOOT_CFE) { ++ ret = kerSysNvRamSet(ctrlParms.string, ctrlParms.strLen, ctrlParms.offset); ++ } ++ else { ++ printk("RedBoot : not supported\n"); ++ return(-EINVAL); ++ } ++ break; ++ + case BCM_IMAGE_CFE: + if (boot_loader_type == BOOT_CFE) { ++ if( ctrlParms.strLen <= 0 || ctrlParms.strLen > FLASH45_LENGTH_BOOT_ROM ) ++ { + printk("Illegal CFE size [%d]. Size allowed: [%d]\n", ++ ctrlParms.strLen, FLASH45_LENGTH_BOOT_ROM); ++ ret = -1; ++ break; ++ } ++ ++ // save NVRAM data into a local structure ++ memcpy( &SaveNvramData, pNvramData, sizeof(NVRAM_DATA) ); ++ ++ ret = kerSysBcmImageSet(ctrlParms.offset, ctrlParms.string, ctrlParms.strLen); ++ ++ // if nvram is not valid, restore the current nvram settings ++ if( BpSetBoardId( pNvramData->szBoardId ) != BP_SUCCESS && ++ *(unsigned long *) pNvramData == NVRAM_DATA_ID ) ++ { ++ kerSysNvRamSet((char *) &SaveNvramData, sizeof(SaveNvramData), 0); ++ } ++ } ++ else { ++ printk("RedBoot : not supported\n"); ++ return(-EINVAL); ++ } ++ break; ++ case BCM_IMAGE_FS: + if (boot_loader_type == BOOT_CFE) { ++ allowedSize = (int) flash_get_total_size() - FLASH_RESERVED_AT_END - TAG_LEN - FLASH45_LENGTH_BOOT_ROM; ++ if( ctrlParms.strLen <= 0 || ctrlParms.strLen > allowedSize) ++ { ++ printk("Illegal root file system size [%d]. Size allowed: [%d]\n", ++ ctrlParms.strLen, ctrlParms.offset - allowedSize); ++ ret = -1; ++ break; ++ } ++ ret = kerSysBcmImageSet(ctrlParms.offset, ctrlParms.string, ctrlParms.strLen); ++ kerSysMipsSoftReset(); ++ } ++ else { ++ printk("RedBoot : not supported\n"); ++ return(-EINVAL); ++ } ++ break; ++ ++ case BCM_IMAGE_KERNEL: // not used for now. + if (boot_loader_type == BOOT_CFE) { ++ allowedSize = (int) flash_get_total_size() - FLASH_RESERVED_AT_END - TAG_LEN - ctrlParms.offset; ++ ++ printk("kernel size = [%d]. Allowed size = [%d]\n", ctrlParms.strLen, allowedSize); ++ ++ if( ctrlParms.strLen <= 0 || ctrlParms.strLen > allowedSize ) ++ { ++ printk("Kernel size is over the limit by [%d] bytes\n", ++ ctrlParms.strLen - allowedSize); ++ ret = -1; ++ break; ++ } ++ ret = kerSysBcmImageSet(ctrlParms.offset, ctrlParms.string, ctrlParms.strLen); ++ } ++ else { ++ printk("RedBoot : not supported\n"); ++ return(-EINVAL); ++ } ++ break; ++ case BCM_IMAGE_WHOLE: + if (boot_loader_type == BOOT_CFE) { ++ if(ctrlParms.strLen <= 0) ++ { ++ printk("Illegal flash image size [%d].\n", ctrlParms.strLen); ++ ret = -1; ++ break; ++ } ++ ++ // save NVRAM data into a local structure ++ memcpy( &SaveNvramData, pNvramData, sizeof(NVRAM_DATA) ); ++ ++ ret = kerSysBcmImageSet(ctrlParms.offset, ctrlParms.string, ctrlParms.strLen); ++ ++ // if nvram is not valid, restore the current nvram settings ++ if( BpSetBoardId( pNvramData->szBoardId ) != BP_SUCCESS && ++ *(unsigned long *) pNvramData == NVRAM_DATA_ID ) ++ { ++ kerSysNvRamSet((char *) &SaveNvramData, sizeof(SaveNvramData), 0); ++ } ++ ++ kerSysMipsSoftReset(); ++ } ++ else { ++ printk("RedBoot : not supported\n"); ++ return(-EINVAL); ++ } ++ break; ++ ++ default: ++ ret = -EINVAL; ++ printk("flash_ioctl_command: invalid command %d\n", ctrlParms.action); ++ break; ++ } ++ ctrlParms.result = ret; ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS)); ++ } ++ else ++ ret = -EFAULT; ++ break; ++ ++ case BOARD_IOCTL_FLASH_READ: ++ if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) ++ { ++ switch (ctrlParms.action) ++ { ++ case SCRATCH_PAD: + if (boot_loader_type == BOOT_CFE) { ++ ret = kerSysScratchPadGet(ctrlParms.string, ctrlParms.buf, ctrlParms.offset); ++ } ++ else { ++ printk("RedBoot : not supported\n"); ++ return(-EINVAL); ++ } ++ break; ++ ++ case PERSISTENT: + if (boot_loader_type == BOOT_CFE) { ++ ret = kerSysPersistentGet(ctrlParms.string, ctrlParms.strLen, ctrlParms.offset); ++ } ++ else { ++ printk("RedBoot : not supported\n"); ++ return(-EINVAL); ++ } ++ break; ++ ++ case NVRAM: + if (boot_loader_type == BOOT_CFE) { ++ ret = kerSysNvRamGet(ctrlParms.string, ctrlParms.strLen, ctrlParms.offset); ++ } ++ else { ++ printk("RedBoot : not supported\n"); ++ return(-EINVAL); ++ } ++ break; ++ ++ case FLASH_SIZE: + if (boot_loader_type == BOOT_CFE) { ++ ret = kerSysFlashSizeGet(); ++ } ++ else { ++ printk("RedBoot : not supported\n"); ++ return(-EINVAL); ++ } ++ break; ++ ++ default: ++ ret = -EINVAL; ++ printk("Not supported. invalid command %d\n", ctrlParms.action); ++ break; ++ } ++ ctrlParms.result = ret; ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS)); ++ } ++ else ++ ret = -EFAULT; ++ break; ++ ++ case BOARD_IOCTL_GET_NR_PAGES: ++ ctrlParms.result = nr_free_pages() + get_page_cache_size(); ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS)); ++ ret = 0; ++ break; ++ ++ case BOARD_IOCTL_DUMP_ADDR: ++ if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) ++ { ++ dumpaddr( (unsigned char *) ctrlParms.string, ctrlParms.strLen ); ++ ctrlParms.result = 0; ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS)); ++ ret = 0; ++ } ++ else ++ ret = -EFAULT; ++ break; ++ ++ case BOARD_IOCTL_SET_MEMORY: + if (boot_loader_type == BOOT_CFE) { ++ if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) ++ { ++ unsigned long *pul = (unsigned long *) ctrlParms.string; ++ unsigned short *pus = (unsigned short *) ctrlParms.string; ++ unsigned char *puc = (unsigned char *) ctrlParms.string; ++ switch( ctrlParms.strLen ) ++ { ++ case 4: ++ *pul = (unsigned long) ctrlParms.offset; ++ break; ++ case 2: ++ *pus = (unsigned short) ctrlParms.offset; ++ break; ++ case 1: ++ *puc = (unsigned char) ctrlParms.offset; ++ break; ++ } ++ dumpaddr( (unsigned char *) ctrlParms.string, sizeof(long) ); ++ ctrlParms.result = 0; ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS)); ++ ret = 0; ++ } ++ else ++ ret = -EFAULT; ++ } ++ else { ++ printk("RedBoot : not supported\n"); ++ return(-EINVAL); ++ ++ } ++ break; ++ ++ case BOARD_IOCTL_MIPS_SOFT_RESET: ++ kerSysMipsSoftReset(); ++ break; ++ ++ case BOARD_IOCTL_LED_CTRL: ++ if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) ++ { ++ kerSysLedCtrl((BOARD_LED_NAME)ctrlParms.strLen, (BOARD_LED_STATE)ctrlParms.offset); ++ ret = 0; ++ } ++ break; ++ ++ case BOARD_IOCTL_GET_ID: + if (boot_loader_type == BOOT_CFE) { ++ if (copy_from_user((void*)&ctrlParms, (void*)arg, ++ sizeof(ctrlParms)) == 0) ++ { ++ if( ctrlParms.string ) ++ { ++ char *p = (char *) get_system_type(); ++ if( strlen(p) + 1 < ctrlParms.strLen ) ++ ctrlParms.strLen = strlen(p) + 1; ++ __copy_to_user(ctrlParms.string, p, ctrlParms.strLen); ++ } ++ ++ ctrlParms.result = 0; ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, ++ sizeof(BOARD_IOCTL_PARMS)); ++ } ++ } ++ else { ++ printk("RedBoot : not supported\n"); ++ return(-EINVAL); ++ } ++ break; ++ ++ case BOARD_IOCTL_GET_MAC_ADDRESS: + if (boot_loader_type == BOOT_CFE) { ++ if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) ++ { ++ ctrlParms.result = kerSysGetMacAddress( ucaMacAddr, ++ ctrlParms.offset ); ++ ++ if( ctrlParms.result == 0 ) ++ { ++ __copy_to_user(ctrlParms.string, ucaMacAddr, ++ sizeof(ucaMacAddr)); ++ } ++ ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, ++ sizeof(BOARD_IOCTL_PARMS)); ++ ret = 0; ++ } ++ else ++ ret = -EFAULT; ++ } ++ else { ++ printk("RedBoot : not supported\n"); ++ return(-EINVAL); ++ } ++ break; ++ ++ case BOARD_IOCTL_RELEASE_MAC_ADDRESS: + if (boot_loader_type == BOOT_CFE) { ++ if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) ++ { ++ if (copy_from_user((void*)ucaMacAddr, (void*)ctrlParms.string, \ ++ NVRAM_MAC_ADDRESS_LEN) == 0) ++ { ++ ctrlParms.result = kerSysReleaseMacAddress( ucaMacAddr ); ++ } ++ else ++ { ++ ctrlParms.result = -EACCES; ++ } ++ ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, ++ sizeof(BOARD_IOCTL_PARMS)); ++ ret = 0; ++ } ++ else ++ ret = -EFAULT; ++ } ++ else { ++ printk("RedBoot : not supported\n"); ++ return(-EINVAL); ++ } ++ break; ++ ++ case BOARD_IOCTL_GET_PSI_SIZE: + if (boot_loader_type == BOOT_CFE) { ++ ctrlParms.result = (int) g_pNvramInfo->ulPsiSize; ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS)); ++ ret = 0; ++ } ++ else { ++ printk("RedBoot : not supported\n"); ++ return(-EINVAL); ++ } ++ break; ++ ++ case BOARD_IOCTL_GET_SDRAM_SIZE: + if (boot_loader_type == BOOT_CFE) { ++ ctrlParms.result = (int) g_pNvramInfo->ulSdramSize; ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS)); ++ ret = 0; ++ } ++ else { ++ printk("RedBoot : not supported\n"); ++ return(-EINVAL); ++ } ++ break; ++ ++ case BOARD_IOCTL_GET_BASE_MAC_ADDRESS: ++ if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) ++ { ++ __copy_to_user(ctrlParms.string, g_pNvramInfo->ucaBaseMacAddr, NVRAM_MAC_ADDRESS_LEN); ++ ctrlParms.result = 0; ++ ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, ++ sizeof(BOARD_IOCTL_PARMS)); ++ ret = 0; ++ } ++ else ++ ret = -EFAULT; ++ break; ++ ++ case BOARD_IOCTL_GET_CHIP_ID: ++ ctrlParms.result = (int) (PERF->RevID & 0xFFFF0000) >> 16; ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS)); ++ ret = 0; ++ break; ++ ++ case BOARD_IOCTL_GET_NUM_ENET: { ++ ETHERNET_MAC_INFO EnetInfos[BP_MAX_ENET_MACS]; ++ int i, numeth = 0; ++ if (BpGetEthernetMacInfo(EnetInfos, BP_MAX_ENET_MACS) == BP_SUCCESS) { ++ for( i = 0; i < BP_MAX_ENET_MACS; i++) { ++ if (EnetInfos[i].ucPhyType != BP_ENET_NO_PHY) { ++ numeth++; ++ } ++ } ++ ctrlParms.result = numeth; ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS)); ++ ret = 0; ++ } ++ else { ++ ret = -EFAULT; ++ } ++ break; ++ } ++ + case BOARD_IOCTL_GET_CFE_VER: ++ if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) { + char *vertag = (char *)(FLASH_BASE + CFE_VERSION_OFFSET); + if (ctrlParms.strLen < CFE_VERSION_SIZE) { ++ ctrlParms.result = 0; ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS)); ++ ret = -EFAULT; ++ } ++ else if (strncmp(vertag, "cfe-v", 5)) { // no tag info in flash ++ ctrlParms.result = 0; ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS)); ++ ret = 0; ++ } ++ else { ++ ctrlParms.result = 1; + __copy_to_user(ctrlParms.string, vertag+CFE_VERSION_MARK_SIZE, CFE_VERSION_SIZE); ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS)); ++ ret = 0; ++ } ++ } ++ else { ++ ret = -EFAULT; ++ } ++ break; ++ ++ case BOARD_IOCTL_GET_ENET_CFG: ++ if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) { ++ ETHERNET_MAC_INFO EnetInfos[BP_MAX_ENET_MACS]; ++ if (BpGetEthernetMacInfo(EnetInfos, BP_MAX_ENET_MACS) == BP_SUCCESS) { ++ if (ctrlParms.strLen == sizeof(EnetInfos)) { ++ __copy_to_user(ctrlParms.string, EnetInfos, sizeof(EnetInfos)); ++ ctrlParms.result = 0; ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS)); ++ ret = 0; ++ } else ++ ret = -EFAULT; ++ } ++ else { ++ ret = -EFAULT; ++ } ++ break; ++ } ++ else { ++ ret = -EFAULT; ++ } ++ break; ++//<<JUNHON, 2004/09/15, get reset button status , tim hou , 05/04/12 ++ case BOARD_IOCTL_GET_RESETHOLD: ++ ctrlParms.result = kerSysGetResetHold(); ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS)); ++ ret = 0; ++ break; ++//>>JUNHON, 2004/09/15 ++ ++ ++#if defined (WIRELESS) ++ case BOARD_IOCTL_GET_WLAN_ANT_INUSE: ++ if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) { ++ unsigned short antInUse = 0; ++ if (BpGetWirelessAntInUse(&antInUse) == BP_SUCCESS) { ++ if (ctrlParms.strLen == sizeof(antInUse)) { ++ __copy_to_user(ctrlParms.string, &antInUse, sizeof(antInUse)); ++ ctrlParms.result = 0; ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS)); ++ ret = 0; ++ } else ++ ret = -EFAULT; ++ } ++ else { ++ ret = -EFAULT; ++ } ++ break; ++ } ++ else { ++ ret = -EFAULT; ++ } ++ break; ++#endif ++ case BOARD_IOCTL_SET_TRIGGER_EVENT: ++ if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) { ++ BOARD_IOC *board_ioc = (BOARD_IOC *)flip->private_data; ++ ctrlParms.result = -EFAULT; ++ ret = -EFAULT; ++ if (ctrlParms.strLen == sizeof(unsigned long)) { ++ board_ioc->eventmask |= *((int*)ctrlParms.string); ++#if defined (WIRELESS) ++ if((board_ioc->eventmask & SES_EVENTS)) { ++ if(sesBtn_irq != BP_NOT_DEFINED) { ++ BcmHalInterruptEnable(sesBtn_irq); ++ ctrlParms.result = 0; ++ ret = 0; ++ } ++ } ++#endif ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS)); ++ } ++ break; ++ } ++ else { ++ ret = -EFAULT; ++ } ++ break; ++ ++ case BOARD_IOCTL_GET_TRIGGER_EVENT: ++ if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) { ++ BOARD_IOC *board_ioc = (BOARD_IOC *)flip->private_data; ++ if (ctrlParms.strLen == sizeof(unsigned long)) { ++ __copy_to_user(ctrlParms.string, &board_ioc->eventmask, sizeof(unsigned long)); ++ ctrlParms.result = 0; ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS)); ++ ret = 0; ++ } else ++ ret = -EFAULT; ++ ++ break; ++ } ++ else { ++ ret = -EFAULT; ++ } ++ break; ++ ++ case BOARD_IOCTL_UNSET_TRIGGER_EVENT: ++ if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) { ++ if (ctrlParms.strLen == sizeof(unsigned long)) { ++ BOARD_IOC *board_ioc = (BOARD_IOC *)flip->private_data; ++ board_ioc->eventmask &= (~(*((int*)ctrlParms.string))); ++ ctrlParms.result = 0; ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS)); ++ ret = 0; ++ } else ++ ret = -EFAULT; ++ ++ break; ++ } ++ else { ++ ret = -EFAULT; ++ } ++ break; ++#if defined (WIRELESS) ++ case BOARD_IOCTL_SET_SES_LED: ++ if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) { ++ if (ctrlParms.strLen == sizeof(int)) { ++ sesLed_ctrl(*(int*)ctrlParms.string); ++ ctrlParms.result = 0; ++ __copy_to_user((BOARD_IOCTL_PARMS*)arg, &ctrlParms, sizeof(BOARD_IOCTL_PARMS)); ++ ret = 0; ++ } else ++ ret = -EFAULT; ++ ++ break; ++ } ++ else { ++ ret = -EFAULT; ++ } ++ break; ++#endif ++ ++ case BOARD_IOCTL_SET_MONITOR_FD: ++ if (copy_from_user((void*)&ctrlParms, (void*)arg, sizeof(ctrlParms)) == 0) { ++ int fput_needed = 0; ++ ++ g_monitor_file = fget_light( ctrlParms.offset, &fput_needed ); ++ if( g_monitor_file ) { ++ /* Hook this file descriptor's poll function in order to set ++ * the exception descriptor when there is a change in link ++ * state. ++ */ ++ g_monitor_task = current; ++ g_orig_fop_poll = kerSysMonitorPollHook; ++ /*g_orig_fop_poll = g_monitor_file->f_op->poll; ++ g_monitor_file->f_op->poll = kerSysMonitorPollHook;*/ ++ } ++ } ++ break; ++ ++ case BOARD_IOCTL_WAKEUP_MONITOR_TASK: ++ kerSysWakeupMonitorTask(); ++ break; ++ ++ default: ++ ret = -EINVAL; ++ ctrlParms.result = 0; ++ printk("board_ioctl: invalid command %x, cmd %d .\n",command,_IOC_NR(command)); ++ break; ++ ++ } /* switch */ ++ ++ return (ret); ++ ++} /* board_ioctl */ ++ ++/*************************************************************************** ++ * SES Button ISR/GPIO/LED functions. ++ ***************************************************************************/ ++#if defined (WIRELESS) ++static irqreturn_t sesBtn_isr(int irq, void *dev_id, struct pt_regs *ptregs) ++{ ++#if defined(_BCM96338_) || defined(CONFIG_BCM96338) ++ unsigned long gpio_mask = GPIO_NUM_TO_MASK(sesBtn_gpio); ++ volatile unsigned long *gpio_reg = &GPIO->GPIOio; ++#endif ++#if defined(_BCM96345_) || defined(CONFIG_BCM96345) ++ unsigned short gpio_mask = GPIO_NUM_TO_MASK(sesBtn_gpio); ++ volatile unsigned short *gpio_reg = &GPIO->GPIOio; ++#endif ++#if defined(_BCM96348_) || defined (CONFIG_BCM96348) ++ unsigned long gpio_mask = GPIO_NUM_TO_MASK(sesBtn_gpio); ++ volatile unsigned long *gpio_reg = &GPIO->GPIOio; ++ ++ if( (sesBtn_gpio & ~BP_ACTIVE_MASK) >= 32 ) ++ { ++ gpio_mask = GPIO_NUM_TO_MASK_HIGH(sesBtn_gpio); ++ gpio_reg = &GPIO->GPIOio_high; ++ } ++#endif ++ ++ if (!(*gpio_reg & gpio_mask)){ ++ wake_up_interruptible(&g_board_wait_queue); ++ return IRQ_RETVAL(1); ++ } else { ++ return IRQ_RETVAL(0); ++ } ++} ++ ++static void __init sesBtn_mapGpio() ++{ ++ if( BpGetWirelessSesBtnGpio(&sesBtn_gpio) == BP_SUCCESS ) ++ { ++ printk("SES: Button GPIO 0x%x is enabled\n", sesBtn_gpio); ++ } ++} ++ ++static void __init sesBtn_mapIntr(int context) ++{ ++ if( BpGetWirelessSesExtIntr(&sesBtn_irq) == BP_SUCCESS ) ++ { ++ printk("SES: Button Interrupt 0x%x is enabled\n", sesBtn_irq); ++ } ++ else ++ return; ++ ++ sesBtn_irq += INTERRUPT_ID_EXTERNAL_0; ++ ++ if (BcmHalMapInterrupt((FN_HANDLER)sesBtn_isr, context, sesBtn_irq)) { ++ printk("SES: Interrupt mapping failed\n"); ++ } ++ BcmHalInterruptEnable(sesBtn_irq); ++} ++ ++ ++static unsigned int sesBtn_poll(struct file *file, struct poll_table_struct *wait) ++{ ++#if defined(_BCM96338_) || defined(CONFIG_BCM96338) ++ unsigned long gpio_mask = GPIO_NUM_TO_MASK(sesBtn_gpio); ++ volatile unsigned long *gpio_reg = &GPIO->GPIOio; ++#endif ++#if defined(_BCM96345_) || defined(CONFIG_BCM96345) ++ unsigned short gpio_mask = GPIO_NUM_TO_MASK(sesBtn_gpio); ++ volatile unsigned short *gpio_reg = &GPIO->GPIOio; ++#endif ++#if defined(_BCM96348_) || defined (CONFIG_BCM96348) ++ unsigned long gpio_mask = GPIO_NUM_TO_MASK(sesBtn_gpio); ++ volatile unsigned long *gpio_reg = &GPIO->GPIOio; ++ ++ if( (sesBtn_gpio & ~BP_ACTIVE_MASK) >= 32 ) ++ { ++ gpio_mask = GPIO_NUM_TO_MASK_HIGH(sesBtn_gpio); ++ gpio_reg = &GPIO->GPIOio_high; ++ } ++#endif ++ ++ if (!(*gpio_reg & gpio_mask)){ ++ return POLLIN; ++ } ++ return 0; ++} ++ ++static ssize_t sesBtn_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) ++{ ++ volatile unsigned int event=0; ++ ssize_t ret=0; ++ ++#if defined(_BCM96338_) || defined (CONFIG_BCM96338) ++ unsigned long gpio_mask = GPIO_NUM_TO_MASK(sesBtn_gpio); ++ volatile unsigned long *gpio_reg = &GPIO->GPIOio; ++#endif ++#if defined(_BCM96345_) || defined (CONFIG_BCM96345) ++ unsigned short gpio_mask = GPIO_NUM_TO_MASK(sesBtn_gpio); ++ volatile unsigned short *gpio_reg = &GPIO->GPIOio; ++#endif ++#if defined(_BCM96348_) || defined (CONFIG_BCM96348) ++ unsigned long gpio_mask = GPIO_NUM_TO_MASK(sesBtn_gpio); ++ volatile unsigned long *gpio_reg = &GPIO->GPIOio; ++ ++ if( (sesBtn_gpio & ~BP_ACTIVE_MASK) >= 32 ) ++ { ++ gpio_mask = GPIO_NUM_TO_MASK_HIGH(sesBtn_gpio); ++ gpio_reg = &GPIO->GPIOio_high; ++ } ++#endif ++ ++ if(*gpio_reg & gpio_mask){ ++ BcmHalInterruptEnable(sesBtn_irq); ++ return ret; ++ } ++ event = SES_EVENTS; ++ __copy_to_user((char*)buffer, (char*)&event, sizeof(event)); ++ BcmHalInterruptEnable(sesBtn_irq); ++ count -= sizeof(event); ++ buffer += sizeof(event); ++ ret += sizeof(event); ++ return ret; ++} ++ ++static void __init sesLed_mapGpio() ++{ ++ if( BpGetWirelessSesBtnGpio(&sesLed_gpio) == BP_SUCCESS ) ++ { ++ printk("SES: LED GPIO 0x%x is enabled\n", sesBtn_gpio); ++ } ++} ++ ++static void sesLed_ctrl(int action) ++{ ++ ++ //char status = ((action >> 8) & 0xff); /* extract status */ ++ //char event = ((action >> 16) & 0xff); /* extract event */ ++ //char blinktype = ((action >> 24) & 0xff); /* extract blink type for SES_LED_BLINK */ ++ ++ BOARD_LED_STATE led; ++ ++ if(sesLed_gpio == BP_NOT_DEFINED) ++ return; ++ ++ action &= 0xff; /* extract led */ ++ ++ //printk("blinktype=%d, event=%d, status=%d\n",(int)blinktype, (int)event, (int)status); ++ ++ switch (action) ++ { ++ case SES_LED_ON: ++ //printk("SES: led on\n"); ++ led = kLedStateOn; ++ break; ++ case SES_LED_BLINK: ++ //printk("SES: led blink\n"); ++ led = kLedStateSlowBlinkContinues; ++ break; ++ case SES_LED_OFF: ++ default: ++ //printk("SES: led off\n"); ++ led = kLedStateOff; ++ } ++ ++ kerSysLedCtrl(kLedSes, led); ++} ++ ++static void __init ses_board_init() ++{ ++ sesBtn_mapGpio(); ++ sesBtn_mapIntr(0); ++ sesLed_mapGpio(); ++} ++static void __exit ses_board_deinit() ++{ ++ if(sesBtn_irq) ++ BcmHalInterruptDisable(sesBtn_irq); ++} ++#endif ++ ++/*************************************************************************** ++ * Dying gasp ISR and functions. ++ ***************************************************************************/ ++#define KERSYS_DBG printk ++ ++#if defined(CONFIG_BCM96345) ++#define CYCLE_PER_US 70 ++#elif defined(CONFIG_BCM96348) || defined(CONFIG_BCM96338) ++/* The BCM6348 cycles per microsecond is really variable since the BCM6348 ++ * MIPS speed can vary depending on the PLL settings. However, an appoximate ++ * value of 120 will still work OK for the test being done. ++ */ ++#define CYCLE_PER_US 120 ++#endif ++#define DG_GLITCH_TO (100*CYCLE_PER_US) ++ ++static void __init kerSysDyingGaspMapIntr() ++{ ++ unsigned long ulIntr; ++ ++#if defined(CONFIG_BCM96348) || defined(_BCM96348_) || defined(CONFIG_BCM96338) || defined(_BCM96338_) ++ if( BpGetAdslDyingGaspExtIntr( &ulIntr ) == BP_SUCCESS ) { ++ BcmHalMapInterrupt((FN_HANDLER)kerSysDyingGaspIsr, 0, INTERRUPT_ID_DG); ++ BcmHalInterruptEnable( INTERRUPT_ID_DG ); ++ } ++#elif defined(CONFIG_BCM96345) || defined(_BCM96345_) ++ if( BpGetAdslDyingGaspExtIntr( &ulIntr ) == BP_SUCCESS ) { ++ ulIntr += INTERRUPT_ID_EXTERNAL_0; ++ BcmHalMapInterrupt((FN_HANDLER)kerSysDyingGaspIsr, 0, ulIntr); ++ BcmHalInterruptEnable( ulIntr ); ++ } ++#endif ++ ++} ++ ++void kerSysSetWdTimer(ulong timeUs) ++{ ++ TIMER->WatchDogDefCount = timeUs * (FPERIPH/1000000); ++ TIMER->WatchDogCtl = 0xFF00; ++ TIMER->WatchDogCtl = 0x00FF; ++} ++ ++ulong kerSysGetCycleCount(void) ++{ ++ ulong cnt; ++#ifdef _WIN32_WCE ++ cnt = 0; ++#else ++ __asm volatile("mfc0 %0, $9":"=d"(cnt)); ++#endif ++ return(cnt); ++} ++ ++static Bool kerSysDyingGaspCheckPowerLoss(void) ++{ ++ ulong clk0; ++ ulong ulIntr; ++ ++ ulIntr = 0; ++ clk0 = kerSysGetCycleCount(); ++ ++ UART->Data = 'D'; ++ UART->Data = '%'; ++ UART->Data = 'G'; ++ ++#if defined(CONFIG_BCM96345) ++ BpGetAdslDyingGaspExtIntr( &ulIntr ); ++ ++ do { ++ ulong clk1; ++ ++ clk1 = kerSysGetCycleCount(); /* time cleared */ ++ /* wait a little to get new reading */ ++ while ((kerSysGetCycleCount()-clk1) < CYCLE_PER_US*2) ++ ; ++ } while ((0 == (PERF->ExtIrqCfg & (1 << (ulIntr + EI_STATUS_SHFT)))) && ((kerSysGetCycleCount() - clk0) < DG_GLITCH_TO)); ++ ++ if (PERF->ExtIrqCfg & (1 << (ulIntr + EI_STATUS_SHFT))) { /* power glitch */ ++ BcmHalInterruptEnable( ulIntr + INTERRUPT_ID_EXTERNAL_0); ++ KERSYS_DBG(" - Power glitch detected. Duration: %ld us\n", (kerSysGetCycleCount() - clk0)/CYCLE_PER_US); ++ return 0; ++ } ++#elif (defined(CONFIG_BCM96348) || defined(CONFIG_BCM96338)) && !defined(VXWORKS) ++ do { ++ ulong clk1; ++ ++ clk1 = kerSysGetCycleCount(); /* time cleared */ ++ /* wait a little to get new reading */ ++ while ((kerSysGetCycleCount()-clk1) < CYCLE_PER_US*2) ++ ; ++ } while ((PERF->IrqStatus & (1 << (INTERRUPT_ID_DG - INTERNAL_ISR_TABLE_OFFSET))) && ((kerSysGetCycleCount() - clk0) < DG_GLITCH_TO)); ++ ++ if (!(PERF->IrqStatus & (1 << (INTERRUPT_ID_DG - INTERNAL_ISR_TABLE_OFFSET)))) { ++ BcmHalInterruptEnable( INTERRUPT_ID_DG ); ++ KERSYS_DBG(" - Power glitch detected. Duration: %ld us\n", (kerSysGetCycleCount() - clk0)/CYCLE_PER_US); ++ return 0; ++ } ++#endif ++ return 1; ++} ++ ++static void kerSysDyingGaspShutdown( void ) ++{ ++ kerSysSetWdTimer(1000000); ++#if defined(CONFIG_BCM96345) ++ PERF->blkEnables &= ~(EMAC_CLK_EN | USB_CLK_EN | CPU_CLK_EN); ++#elif defined(CONFIG_BCM96348) ++ PERF->blkEnables &= ~(EMAC_CLK_EN | USBS_CLK_EN | USBH_CLK_EN | SAR_CLK_EN); ++#endif ++} ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) ++static irqreturn_t kerSysDyingGaspIsr(int irq, void * dev_id, struct pt_regs * regs) ++#else ++static unsigned int kerSysDyingGaspIsr(void) ++#endif ++{ ++ struct list_head *pos; ++ CB_DGASP_LIST *tmp, *dsl = NULL; ++ ++ if (kerSysDyingGaspCheckPowerLoss()) { ++ ++ /* first to turn off everything other than dsl */ ++ list_for_each(pos, &g_cb_dgasp_list_head->list) { ++ tmp = list_entry(pos, CB_DGASP_LIST, list); ++ if(strncmp(tmp->name, "dsl", 3)) { ++ (tmp->cb_dgasp_fn)(tmp->context); ++ }else { ++ dsl = tmp; ++ } ++ } ++ ++ /* now send dgasp */ ++ if(dsl) ++ (dsl->cb_dgasp_fn)(dsl->context); ++ ++ /* reset and shutdown system */ ++ kerSysDyingGaspShutdown(); ++ } ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) ++return( IRQ_HANDLED ); ++#else ++ return( 1 ); ++#endif ++} ++ ++static void __init kerSysInitDyingGaspHandler( void ) ++{ ++ CB_DGASP_LIST *new_node; ++ ++ if( g_cb_dgasp_list_head != NULL) { ++ printk("Error: kerSysInitDyingGaspHandler: list head is not null\n"); ++ return; ++ } ++ new_node= (CB_DGASP_LIST *)kmalloc(sizeof(CB_DGASP_LIST), GFP_KERNEL); ++ memset(new_node, 0x00, sizeof(CB_DGASP_LIST)); ++ INIT_LIST_HEAD(&new_node->list); ++ g_cb_dgasp_list_head = new_node; ++ ++} /* kerSysInitDyingGaspHandler */ ++ ++static void __exit kerSysDeinitDyingGaspHandler( void ) ++{ ++ struct list_head *pos; ++ CB_DGASP_LIST *tmp; ++ ++ if(g_cb_dgasp_list_head == NULL) ++ return; ++ ++ list_for_each(pos, &g_cb_dgasp_list_head->list) { ++ tmp = list_entry(pos, CB_DGASP_LIST, list); ++ list_del(pos); ++ kfree(tmp); ++ } ++ ++ kfree(g_cb_dgasp_list_head); ++ g_cb_dgasp_list_head = NULL; ++ ++} /* kerSysDeinitDyingGaspHandler */ ++ ++void kerSysRegisterDyingGaspHandler(char *devname, void *cbfn, void *context) ++{ ++ CB_DGASP_LIST *new_node; ++ ++ if( g_cb_dgasp_list_head == NULL) { ++ printk("Error: kerSysRegisterDyingGaspHandler: list head is null\n"); ++ return; ++ } ++ ++ if( devname == NULL || cbfn == NULL ) { ++ printk("Error: kerSysRegisterDyingGaspHandler: register info not enough (%s,%x,%x)\n", devname, (unsigned int)cbfn, (unsigned int)context); ++ return; ++ } ++ ++ new_node= (CB_DGASP_LIST *)kmalloc(sizeof(CB_DGASP_LIST), GFP_KERNEL); ++ memset(new_node, 0x00, sizeof(CB_DGASP_LIST)); ++ INIT_LIST_HEAD(&new_node->list); ++ strncpy(new_node->name, devname, IFNAMSIZ); ++ new_node->cb_dgasp_fn = (cb_dgasp_t)cbfn; ++ new_node->context = context; ++ list_add(&new_node->list, &g_cb_dgasp_list_head->list); ++ ++ printk("dgasp: kerSysRegisterDyingGaspHandler: %s registered \n", devname); ++ ++} /* kerSysRegisterDyingGaspHandler */ ++ ++void kerSysDeregisterDyingGaspHandler(char *devname) ++{ ++ struct list_head *pos; ++ CB_DGASP_LIST *tmp; ++ ++ if(g_cb_dgasp_list_head == NULL) { ++ printk("Error: kerSysDeregisterDyingGaspHandler: list head is null\n"); ++ return; ++ } ++ ++ if(devname == NULL) { ++ printk("Error: kerSysDeregisterDyingGaspHandler: devname is null\n"); ++ return; ++ } ++ ++ printk("kerSysDeregisterDyingGaspHandler: %s is deregistering\n", devname); ++ ++ list_for_each(pos, &g_cb_dgasp_list_head->list) { ++ tmp = list_entry(pos, CB_DGASP_LIST, list); ++ if(!strcmp(tmp->name, devname)) { ++ list_del(pos); ++ kfree(tmp); ++ printk("kerSysDeregisterDyingGaspHandler: %s is deregistered\n", devname); ++ return; ++ } ++ } ++ printk("kerSysDeregisterDyingGaspHandler: %s not (de)registered\n", devname); ++ ++} /* kerSysDeregisterDyingGaspHandler */ ++ ++/*************************************************************************** ++ * MACRO to call driver initialization and cleanup functions. ++ ***************************************************************************/ ++module_init( brcm_board_init ); ++module_exit( brcm_board_cleanup ); ++ ++EXPORT_SYMBOL(kerSysNvRamGet); ++EXPORT_SYMBOL(dumpaddr); ++EXPORT_SYMBOL(kerSysGetMacAddress); ++EXPORT_SYMBOL(kerSysReleaseMacAddress); ++EXPORT_SYMBOL(kerSysGetSdramSize); ++EXPORT_SYMBOL(kerSysLedCtrl); ++//<<JUNHON, 2004/09/15, get reset button status , tim hou , 05/04/12 ++EXPORT_SYMBOL(kerSysGetResetHold); ++//>>JUNHON, 2004/09/15 ++EXPORT_SYMBOL(kerSysLedRegisterHwHandler); ++EXPORT_SYMBOL(BpGetBoardIds); ++EXPORT_SYMBOL(BpGetSdramSize); ++EXPORT_SYMBOL(BpGetPsiSize); ++EXPORT_SYMBOL(BpGetEthernetMacInfo); ++EXPORT_SYMBOL(BpGetRj11InnerOuterPairGpios); ++EXPORT_SYMBOL(BpGetPressAndHoldResetGpio); ++EXPORT_SYMBOL(BpGetVoipResetGpio); ++EXPORT_SYMBOL(BpGetVoipIntrGpio); ++EXPORT_SYMBOL(BpGetPcmciaResetGpio); ++EXPORT_SYMBOL(BpGetRtsCtsUartGpios); ++EXPORT_SYMBOL(BpGetAdslLedGpio); ++EXPORT_SYMBOL(BpGetAdslFailLedGpio); ++EXPORT_SYMBOL(BpGetWirelessLedGpio); ++EXPORT_SYMBOL(BpGetUsbLedGpio); ++EXPORT_SYMBOL(BpGetHpnaLedGpio); ++EXPORT_SYMBOL(BpGetWanDataLedGpio); ++EXPORT_SYMBOL(BpGetPppLedGpio); ++EXPORT_SYMBOL(BpGetPppFailLedGpio); ++EXPORT_SYMBOL(BpGetVoipLedGpio); ++EXPORT_SYMBOL(BpGetWirelessExtIntr); ++EXPORT_SYMBOL(BpGetAdslDyingGaspExtIntr); ++EXPORT_SYMBOL(BpGetVoipExtIntr); ++EXPORT_SYMBOL(BpGetHpnaExtIntr); ++EXPORT_SYMBOL(BpGetHpnaChipSelect); ++EXPORT_SYMBOL(BpGetVoipChipSelect); ++EXPORT_SYMBOL(BpGetWirelessSesBtnGpio); ++EXPORT_SYMBOL(BpGetWirelessSesExtIntr); ++EXPORT_SYMBOL(BpGetWirelessSesLedGpio); ++EXPORT_SYMBOL(kerSysRegisterDyingGaspHandler); ++EXPORT_SYMBOL(kerSysDeregisterDyingGaspHandler); ++EXPORT_SYMBOL(kerSysGetCycleCount); ++EXPORT_SYMBOL(kerSysSetWdTimer); ++EXPORT_SYMBOL(kerSysWakeupMonitorTask); ++ +diff -urN linux-2.6.17/arch/mips/brcm-boards/bcm963xx/boardparms.c linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/boardparms.c +--- linux-2.6.17/arch/mips/brcm-boards/bcm963xx/boardparms.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/boardparms.c 2006-08-03 16:36:58.000000000 +0200 +@@ -0,0 +1,2391 @@ ++/* ++<:copyright-gpl ++ ++ Copyright 2003 Broadcom Corp. All Rights Reserved. ++ ++ This program is free software; you can distribute it and/or modify it ++ under the terms of the GNU General Public License (Version 2) as ++ published by the Free Software Foundation. ++ ++ This program is distributed in the hope it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ ++:> ++*/ ++/************************************************************************** ++ * File Name : boardparms.c ++ * ++ * Description: This file contains the implementation for the BCM63xx board ++ * parameter access functions. ++ * ++ * Updates : 07/14/2003 Created. ++ ***************************************************************************/ ++ ++/* Includes. */ ++#include "boardparms.h" ++ ++/* Defines. */ ++ ++/* Default psi size in K bytes */ ++#define BP_PSI_DEFAULT_SIZE 24 ++ ++/* Typedefs */ ++typedef struct boardparameters ++{ ++ char szBoardId[BP_BOARD_ID_LEN]; /* board id string */ ++ ETHERNET_MAC_INFO EnetMacInfos[BP_MAX_ENET_MACS]; ++ VOIP_DSP_INFO VoIPDspInfo[BP_MAX_VOIP_DSP]; ++ unsigned short usSdramSize; /* SDRAM size and type */ ++ unsigned short usPsiSize; /* persistent storage in K bytes */ ++ unsigned short usGpioRj11InnerPair; /* GPIO pin or not defined */ ++ unsigned short usGpioRj11OuterPair; /* GPIO pin or not defined */ ++ unsigned short usGpioPressAndHoldReset; /* GPIO pin or not defined */ ++ unsigned short usGpioPcmciaReset; /* GPIO pin or not defined */ ++ unsigned short usGpioUartRts; /* GPIO pin or not defined */ ++ unsigned short usGpioUartCts; /* GPIO pin or not defined */ ++ unsigned short usGpioLedAdsl; /* GPIO pin or not defined */ ++ unsigned short usGpioLedAdslFail; /* GPIO pin or not defined */ ++ unsigned short usGpioLedWireless; /* GPIO pin or not defined */ ++ unsigned short usGpioLedUsb; /* GPIO pin or not defined */ ++ unsigned short usGpioLedHpna; /* GPIO pin or not defined */ ++ unsigned short usGpioLedWanData; /* GPIO pin or not defined */ ++ unsigned short usGpioLedPpp; /* GPIO pin or not defined */ ++ unsigned short usGpioLedPppFail; /* GPIO pin or not defined */ ++ unsigned short usGpioLedBlPowerOn; /* GPIO pin or not defined */ ++ unsigned short usGpioLedBlAlarm; /* GPIO pin or not defined */ ++ unsigned short usGpioLedBlResetCfg; /* GPIO pin or not defined */ ++ unsigned short usGpioLedBlStop; /* GPIO pin or not defined */ ++ unsigned short usExtIntrWireless; /* ext intr or not defined */ ++ unsigned short usExtIntrAdslDyingGasp; /* ext intr or not defined */ ++ unsigned short usExtIntrHpna; /* ext intr or not defined */ ++ unsigned short usCsHpna; /* chip select not defined */ ++ unsigned short usAntInUseWireless; /* antenna in use or not defined */ ++ unsigned short usGpioSesBtnWireless; /* GPIO pin or not defined */ ++ unsigned short usExtIntrSesBtnWireless; /* ext intr or not defined */ ++ unsigned short usGpioLedSesWireless; /* GPIO pin or not defined */ ++} BOARD_PARAMETERS, *PBOARD_PARAMETERS; ++ ++/* Variables */ ++#if defined(_BCM96338_) || defined(CONFIG_BCM96338) ++static BOARD_PARAMETERS g_bcm96338sv = ++{ ++ "96338SV", /* szBoardId */ ++ {{BP_ENET_INTERNAL_PHY, /* ucPhyType */ ++ 0x01, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x01, /* numSwitchPorts */ ++ BP_ENET_CONFIG_MDIO, /* usConfigType */ ++ BP_NOT_DEFINED}, /* usReverseMii */ ++ {BP_ENET_NO_PHY}}, /* ucPhyType */ ++ {{BP_VOIP_NO_DSP}, /* ucDspType */ ++ {BP_VOIP_NO_DSP}}, /* ucDspType */ ++ BP_MEMORY_16MB_1_CHIP, /* usSdramSize */ ++ BP_PSI_DEFAULT_SIZE, /* usPsiSize */ ++ BP_NOT_DEFINED, /* usGpioRj11InnerPair */ ++ BP_NOT_DEFINED, /* usGpioRj11OuterPair */ ++ BP_NOT_DEFINED, /* usGpioPressAndHoldReset */ ++ BP_NOT_DEFINED, /* usGpioPcmciaReset */ ++ BP_NOT_DEFINED, /* usGpioUartRts */ ++ BP_NOT_DEFINED, /* usGpioUartCts */ ++ BP_NOT_DEFINED, /* usGpioLedAdsl */ ++ BP_NOT_DEFINED, /* usGpioLedAdslFail */ ++ BP_NOT_DEFINED, /* usGpioLedWireless */ ++ BP_NOT_DEFINED, /* usGpioLedUsb */ ++ BP_NOT_DEFINED, /* usGpioLedHpna */ ++ BP_NOT_DEFINED, /* usGpioLedWanData */ ++ BP_NOT_DEFINED, /* usGpioLedPpp */ ++ BP_NOT_DEFINED, /* usGpioLedPppFail */ ++ BP_NOT_DEFINED, /* usGpioLedBlPowerOn */ ++ BP_NOT_DEFINED, /* usGpioLedBlAlarm */ ++ BP_NOT_DEFINED, /* usGpioLedBlResetCfg */ ++ BP_NOT_DEFINED, /* usGpioLedBlStop */ ++ BP_NOT_DEFINED, /* usExtIntrWireless */ ++ BP_HW_DEFINED, /* usExtIntrAdslDyingGasp */ ++ BP_NOT_DEFINED, /* usExtIntrHpna */ ++ BP_NOT_DEFINED, /* usCsHpna */ ++ BP_NOT_DEFINED, /* usAntInUseWireless */ ++ BP_NOT_DEFINED, /* usGpioSesBtnWireless */ ++ BP_NOT_DEFINED, /* usExtIntrSesBtnWireless */ ++ BP_NOT_DEFINED /* usGpioLedSesWireless */ ++}; ++static BOARD_PARAMETERS g_bcm96338l2m8m = ++{ ++ "96338L-2M-8M", /* szBoardId */ ++ {{BP_ENET_INTERNAL_PHY, /* ucPhyType */ ++ 0x01, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x01, /* numSwitchPorts */ ++ BP_ENET_CONFIG_MDIO, /* usConfigType */ ++ BP_NOT_DEFINED}, /* usReverseMii */ ++ {BP_ENET_NO_PHY}}, /* ucPhyType */ ++ {{BP_VOIP_NO_DSP}, /* ucDspType */ ++ {BP_VOIP_NO_DSP}}, /* ucDspType */ ++ BP_MEMORY_8MB_1_CHIP, /* usSdramSize */ ++ BP_PSI_DEFAULT_SIZE, /* usPsiSize */ ++ BP_NOT_DEFINED, /* usGpioRj11InnerPair */ ++ BP_NOT_DEFINED, /* usGpioRj11OuterPair */ ++ BP_NOT_DEFINED, /* usGpioPressAndHoldReset */ ++ BP_NOT_DEFINED, /* usGpioPcmciaReset */ ++ BP_NOT_DEFINED, /* usGpioUartRts */ ++ BP_NOT_DEFINED, /* usGpioUartCts */ ++ BP_NOT_DEFINED, /* usGpioLedAdsl */ ++ BP_GPIO_2_AL, /* usGpioLedAdslFail */ ++ BP_NOT_DEFINED, /* usGpioLedWireless */ ++ BP_NOT_DEFINED, /* usGpioLedUsb */ ++ BP_NOT_DEFINED, /* usGpioLedHpna */ ++ BP_GPIO_3_AL, /* usGpioLedWanData */ ++ BP_GPIO_3_AL, /* usGpioLedPpp */ ++ BP_GPIO_4_AL, /* usGpioLedPppFail */ ++ BP_GPIO_0_AL, /* usGpioLedBlPowerOn */ ++ BP_NOT_DEFINED, /* usGpioLedBlAlarm */ ++ BP_GPIO_3_AL, /* usGpioLedBlResetCfg */ ++ BP_GPIO_1_AL, /* usGpioLedBlStop */ ++ BP_NOT_DEFINED, /* usExtIntrWireless */ ++ BP_HW_DEFINED, /* usExtIntrAdslDyingGasp */ ++ BP_NOT_DEFINED, /* usExtIntrHpna */ ++ BP_NOT_DEFINED, /* usCsHpna */ ++ BP_NOT_DEFINED, /* usAntInUseWireless */ ++ BP_NOT_DEFINED, /* usGpioSesBtnWireless */ ++ BP_NOT_DEFINED, /* usExtIntrSesBtnWireless */ ++ BP_NOT_DEFINED /* usGpioLedSesWireless */ ++}; ++static PBOARD_PARAMETERS g_BoardParms[] = ++ {&g_bcm96338sv, &g_bcm96338l2m8m, 0}; ++#endif ++ ++#if defined(_BCM96345_) || defined(CONFIG_BCM96345) ++static BOARD_PARAMETERS g_bcm96345r = ++{ ++ "96345R", /* szBoardId */ ++ {{BP_ENET_INTERNAL_PHY, /* ucPhyType */ ++ 0x01, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x01, /* numSwitchPorts */ ++ BP_ENET_CONFIG_MDIO, /* usConfigType */ ++ BP_NOT_DEFINED}, /* usReverseMii */ ++ {BP_ENET_NO_PHY}}, /* ucPhyType */ ++ {{BP_VOIP_NO_DSP}, /* ucDspType */ ++ {BP_VOIP_NO_DSP}}, /* ucDspType */ ++ BP_MEMORY_8MB_1_CHIP, /* usSdramSize */ ++ BP_PSI_DEFAULT_SIZE, /* usPsiSize */ ++ BP_GPIO_11_AH, /* usGpioRj11InnerPair */ ++ BP_GPIO_12_AH, /* usGpioRj11OuterPair */ ++ BP_GPIO_13_AH, /* usGpioPressAndHoldReset */ ++ BP_NOT_DEFINED, /* usGpioPcmciaReset */ ++ BP_NOT_DEFINED, /* usGpioUartRts */ ++ BP_NOT_DEFINED, /* usGpioUartCts */ ++ BP_GPIO_8_AH, /* usGpioLedAdsl */ ++ BP_NOT_DEFINED, /* usGpioLedAdslFail */ ++ BP_NOT_DEFINED, /* usGpioLedWireless */ ++ BP_NOT_DEFINED, /* usGpioLedUsb */ ++ BP_NOT_DEFINED, /* usGpioLedHpna */ ++ BP_GPIO_8_AH, /* usGpioLedWanData */ ++ BP_GPIO_9_AH, /* usGpioLedPpp */ ++ BP_NOT_DEFINED, /* usGpioLedPppFail */ ++ BP_NOT_DEFINED, /* usGpioLedBlPowerOn */ ++ BP_GPIO_10_AH, /* usGpioLedBlAlarm */ ++ BP_GPIO_9_AH, /* usGpioLedBlResetCfg */ ++ BP_GPIO_8_AH, /* usGpioLedBlStop */ ++ BP_NOT_DEFINED, /* usExtIntrWireless */ ++ BP_EXT_INTR_0, /* usExtIntrAdslDyingGasp */ ++ BP_NOT_DEFINED, /* usExtIntrHpna */ ++ BP_NOT_DEFINED, /* usCsHpna */ ++ BP_NOT_DEFINED, /* usAntInUseWireless */ ++ BP_NOT_DEFINED, /* usGpioSesBtnWireless */ ++ BP_NOT_DEFINED, /* usExtIntrSesBtnWireless */ ++ BP_NOT_DEFINED /* usGpioLedSesWireless */ ++}; ++ ++static BOARD_PARAMETERS g_bcm96345gw2 = ++{ ++ /* A hardware jumper determines whether GPIO 13 is used for Press and Hold ++ * Reset or RTS. ++ */ ++ "96345GW2", /* szBoardId */ ++ {{BP_ENET_EXTERNAL_SWITCH, /* ucPhyType */ ++ 0x00, /* ucPhyAddress */ ++ BP_GPIO_0_AH, /* usGpioPhySpiSck */ ++ BP_GPIO_4_AH, /* usGpioPhySpiSs */ ++ BP_GPIO_12_AH, /* usGpioPhySpiMosi */ ++ BP_GPIO_11_AH, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x04, /* numSwitchPorts */ ++ BP_ENET_CONFIG_GPIO, /* usConfigType */ ++ BP_ENET_REVERSE_MII}, /* usReverseMii */ ++ {BP_ENET_NO_PHY}}, /* ucPhyType */ ++ {{BP_VOIP_DSP, /* ucDspType */ ++ 0x00, /* ucDspAddress */ ++ BP_EXT_INTR_1, /* usExtIntrVoip */ ++ BP_GPIO_6_AH, /* usGpioVoipReset */ ++ BP_GPIO_15_AH, /* usGpioVoipIntr */ ++ BP_NOT_DEFINED, /* usGpioLedVoip */ ++ BP_CS_2}, /* usCsVoip */ ++ {BP_VOIP_NO_DSP}}, /* ucDspType */ ++ BP_MEMORY_16MB_1_CHIP, /* usSdramSize */ ++ BP_PSI_DEFAULT_SIZE, /* usPsiSize */ ++ BP_NOT_DEFINED, /* usGpioRj11InnerPair */ ++ BP_NOT_DEFINED, /* usGpioRj11OuterPair */ ++ BP_GPIO_13_AH, /* usGpioPressAndHoldReset */ ++ BP_GPIO_2_AH, /* usGpioPcmciaReset */ ++ BP_GPIO_13_AH, /* usGpioUartRts */ ++ BP_GPIO_9_AH, /* usGpioUartCts */ ++ BP_GPIO_8_AH, /* usGpioLedAdsl */ ++ BP_NOT_DEFINED, /* usGpioLedAdslFail */ ++ BP_NOT_DEFINED, /* usGpioLedWireless */ ++ BP_GPIO_7_AH, /* usGpioLedUsb */ ++ BP_NOT_DEFINED, /* usGpioLedHpna */ ++ BP_GPIO_8_AH, /* usGpioLedWanData */ ++ BP_NOT_DEFINED, /* usGpioLedPpp */ ++ BP_NOT_DEFINED, /* usGpioLedPppFail */ ++ BP_NOT_DEFINED, /* usGpioLedBlPowerOn */ ++ BP_GPIO_10_AH, /* usGpioLedBlAlarm */ ++ BP_GPIO_7_AH, /* usGpioLedBlResetCfg */ ++ BP_GPIO_8_AH, /* usGpioLedBlStop */ ++ BP_EXT_INTR_2, /* usExtIntrWireless */ ++ BP_EXT_INTR_0, /* usExtIntrAdslDyingGasp */ ++ BP_NOT_DEFINED, /* usExtIntrHpna */ ++ BP_NOT_DEFINED, /* usCsHpna */ ++ BP_WLAN_ANT_MAIN, /* usAntInUseWireless */ ++ BP_NOT_DEFINED, /* usGpioSesBtnWireless */ ++ BP_NOT_DEFINED, /* usExtIntrSesBtnWireless */ ++ BP_NOT_DEFINED /* usGpioLedSesWireless */ ++}; ++ ++static BOARD_PARAMETERS g_bcm96345gw = ++{ ++ "96345GW", /* szBoardId */ ++ {{BP_ENET_EXTERNAL_SWITCH, /* ucPhyType */ ++ 0x00, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x04, /* numSwitchPorts */ ++ BP_ENET_CONFIG_MDIO, /* usConfigType */ ++ BP_ENET_NO_REVERSE_MII}, /* usReverseMii */ ++ {BP_ENET_NO_PHY}}, /* ucPhyType */ ++ {{BP_VOIP_DSP, /* ucDspType */ ++ 0x00, /* ucDspAddress */ ++ BP_EXT_INTR_1, /* usExtIntrVoip */ ++ BP_GPIO_6_AH, /* usGpioVoipReset */ ++ BP_GPIO_15_AH, /* usGpioVoipIntr */ ++ BP_NOT_DEFINED, /* usGpioLedVoip */ ++ BP_CS_2}, /* usCsVoip */ ++ {BP_VOIP_NO_DSP}}, /* ucDspType */ ++ BP_MEMORY_16MB_1_CHIP, /* usSdramSize */ ++ BP_PSI_DEFAULT_SIZE, /* usPsiSize */ ++ BP_GPIO_11_AH, /* usGpioRj11InnerPair */ ++ BP_GPIO_1_AH, /* usGpioRj11OuterPair */ ++ BP_GPIO_13_AH, /* usGpioPressAndHoldReset */ ++ BP_GPIO_2_AH, /* usGpioPcmciaReset */ ++ BP_NOT_DEFINED, /* usGpioUartRts */ ++ BP_NOT_DEFINED, /* usGpioUartCts */ ++ BP_GPIO_8_AH, /* usGpioLedAdsl */ ++ BP_NOT_DEFINED, /* usGpioLedAdslFail */ ++ BP_GPIO_10_AH, /* usGpioLedWireless */ ++ BP_GPIO_7_AH, /* usGpioLedUsb */ ++ BP_NOT_DEFINED, /* usGpioLedHpna */ ++ BP_GPIO_8_AH, /* usGpioLedWanData */ ++ BP_NOT_DEFINED, /* usGpioLedPpp */ ++ BP_NOT_DEFINED, /* usGpioLedPppFail */ ++ BP_NOT_DEFINED, /* usGpioLedBlPowerOn */ ++ BP_GPIO_9_AH, /* usGpioLedBlAlarm */ ++ BP_GPIO_10_AH, /* usGpioLedBlResetCfg */ ++ BP_GPIO_8_AH, /* usGpioLedBlStop */ ++ BP_EXT_INTR_2, /* usExtIntrWireless */ ++ BP_EXT_INTR_0, /* usExtIntrAdslDyingGasp */ ++ BP_EXT_INTR_3, /* usExtIntrHpna */ ++ BP_CS_1, /* usCsHpna */ ++ BP_WLAN_ANT_MAIN, /* usAntInUseWireless */ ++ BP_NOT_DEFINED, /* usGpioSesBtnWireless */ ++ BP_NOT_DEFINED, /* usExtIntrSesBtnWireless */ ++ BP_NOT_DEFINED /* usGpioLedSesWireless */ ++}; ++ ++static BOARD_PARAMETERS g_bcm96335r = ++{ ++ "96335R", /* szBoardId */ ++ {{BP_ENET_INTERNAL_PHY, /* ucPhyType */ ++ 0x01, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x01, /* numSwitchPorts */ ++ BP_ENET_CONFIG_MDIO, /* usConfigType */ ++ BP_NOT_DEFINED}, /* usReverseMii */ ++ {BP_ENET_NO_PHY}}, /* ucPhyType */ ++ {{BP_VOIP_NO_DSP}, /* ucDspType */ ++ {BP_VOIP_NO_DSP}}, /* ucDspType */ ++ BP_MEMORY_8MB_1_CHIP, /* usSdramSize */ ++ BP_PSI_DEFAULT_SIZE, /* usPsiSize */ ++ BP_NOT_DEFINED, /* usGpioRj11InnerPair */ ++ BP_NOT_DEFINED, /* usGpioRj11OuterPair */ ++ BP_GPIO_14_AH, /* usGpioPressAndHoldReset */ ++ BP_NOT_DEFINED, /* usGpioPcmciaReset */ ++ BP_NOT_DEFINED, /* usGpioUartRts */ ++ BP_NOT_DEFINED, /* usGpioUartCts */ ++ BP_GPIO_9_AH, /* usGpioLedAdsl */ ++ BP_NOT_DEFINED, /* usGpioLedAdslFail */ ++ BP_NOT_DEFINED, /* usGpioLedWireless */ ++ BP_NOT_DEFINED, /* usGpioLedUsb */ ++ BP_NOT_DEFINED, /* usGpioLedHpna */ ++ BP_GPIO_9_AH, /* usGpioLedWanData */ ++ BP_GPIO_8_AH, /* usGpioLedPpp */ ++ BP_NOT_DEFINED, /* usGpioLedPppFail */ ++ BP_NOT_DEFINED, /* usGpioLedBlPowerOn */ ++ BP_GPIO_10_AH, /* usGpioLedBlAlarm */ ++ BP_GPIO_8_AH, /* usGpioLedBlResetCfg */ ++ BP_GPIO_9_AH, /* usGpioLedBlStop */ ++ BP_NOT_DEFINED, /* usExtIntrWireless */ ++ BP_NOT_DEFINED, /* usExtIntrAdslDyingGasp */ ++ BP_NOT_DEFINED, /* usExtIntrHpna */ ++ BP_NOT_DEFINED, /* usCsHpna */ ++ BP_NOT_DEFINED, /* usAntInUseWireless */ ++ BP_NOT_DEFINED, /* usGpioSesBtnWireless */ ++ BP_NOT_DEFINED, /* usExtIntrSesBtnWireless */ ++ BP_NOT_DEFINED /* usGpioLedSesWireless */ ++}; ++ ++static BOARD_PARAMETERS g_bcm96345r0 = ++{ ++ "96345R0", /* szBoardId */ ++ {{BP_ENET_INTERNAL_PHY, /* ucPhyType */ ++ 0x01, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x01, /* numSwitchPorts */ ++ BP_ENET_CONFIG_MDIO, /* usConfigType */ ++ BP_NOT_DEFINED}, /* usReverseMii */ ++ {BP_ENET_NO_PHY}}, /* ucPhyType */ ++ {{BP_VOIP_NO_DSP}, /* ucDspType */ ++ {BP_VOIP_NO_DSP}}, /* ucDspType */ ++ BP_MEMORY_8MB_1_CHIP, /* usSdramSize */ ++ BP_PSI_DEFAULT_SIZE, /* usPsiSize */ ++ BP_NOT_DEFINED, /* usGpioRj11InnerPair */ ++ BP_NOT_DEFINED, /* usGpioRj11OuterPair */ ++ BP_NOT_DEFINED, /* usGpioPressAndHoldReset */ ++ BP_NOT_DEFINED, /* usGpioPcmciaReset */ ++ BP_NOT_DEFINED, /* usGpioUartRts */ ++ BP_NOT_DEFINED, /* usGpioUartCts */ ++ BP_GPIO_8_AH, /* usGpioLedAdsl */ ++ BP_NOT_DEFINED, /* usGpioLedAdslFail */ ++ BP_NOT_DEFINED, /* usGpioLedWireless */ ++ BP_NOT_DEFINED, /* usGpioLedUsb */ ++ BP_NOT_DEFINED, /* usGpioLedHpna */ ++ BP_GPIO_9_AH, /* usGpioLedWanData */ ++ BP_GPIO_9_AH, /* usGpioLedPpp */ ++ BP_NOT_DEFINED, /* usGpioLedPppFail */ ++ BP_NOT_DEFINED, /* usGpioLedBlPowerOn */ ++ BP_GPIO_9_AH, /* usGpioLedBlAlarm */ ++ BP_GPIO_8_AH, /* usGpioLedBlResetCfg */ ++ BP_GPIO_8_AH, /* usGpioLedBlStop */ ++ BP_NOT_DEFINED, /* usExtIntrWireless */ ++ BP_NOT_DEFINED, /* usExtIntrAdslDyingGasp */ ++ BP_NOT_DEFINED, /* usExtIntrHpna */ ++ BP_NOT_DEFINED, /* usCsHpna */ ++ BP_NOT_DEFINED, /* usAntInUseWireless */ ++ BP_NOT_DEFINED, /* usGpioSesBtnWireless */ ++ BP_NOT_DEFINED, /* usExtIntrSesBtnWireless */ ++ BP_NOT_DEFINED /* usGpioLedSesWireless */ ++}; ++ ++static BOARD_PARAMETERS g_bcm96345rs = ++{ ++ "96345RS", /* szBoardId */ ++ {{BP_ENET_EXTERNAL_SWITCH, /* ucPhyType */ ++ 0x00, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x01, /* numSwitchPorts */ ++ BP_ENET_CONFIG_MDIO, /* usConfigType */ ++ BP_ENET_NO_REVERSE_MII}, /* usReverseMii */ ++ {BP_ENET_NO_PHY}}, /* ucPhyType */ ++ {{BP_VOIP_NO_DSP}, /* ucDspType */ ++ {BP_VOIP_NO_DSP}}, /* ucDspType */ ++ BP_MEMORY_8MB_1_CHIP, /* usSdramSize */ ++ BP_PSI_DEFAULT_SIZE, /* usPsiSize */ ++ BP_GPIO_11_AH, /* usGpioRj11InnerPair */ ++ BP_GPIO_12_AH, /* usGpioRj11OuterPair */ ++ BP_GPIO_13_AH, /* usGpioPressAndHoldReset */ ++ BP_NOT_DEFINED, /* usGpioPcmciaReset */ ++ BP_NOT_DEFINED, /* usGpioUartRts */ ++ BP_NOT_DEFINED, /* usGpioUartCts */ ++ BP_GPIO_8_AH, /* usGpioLedAdsl */ ++ BP_NOT_DEFINED, /* usGpioLedAdslFail */ ++ BP_NOT_DEFINED, /* usGpioLedWireless */ ++ BP_NOT_DEFINED, /* usGpioLedUsb */ ++ BP_NOT_DEFINED, /* usGpioLedHpna */ ++ BP_GPIO_8_AH, /* usGpioLedWanData */ ++ BP_GPIO_9_AH, /* usGpioLedPpp */ ++ BP_NOT_DEFINED, /* usGpioLedPppFail */ ++ BP_NOT_DEFINED, /* usGpioLedBlPowerOn */ ++ BP_GPIO_10_AH, /* usGpioLedBlAlarm */ ++ BP_GPIO_9_AH, /* usGpioLedBlResetCfg */ ++ BP_GPIO_8_AH, /* usGpioLedBlStop */ ++ BP_NOT_DEFINED, /* usExtIntrWireless */ ++ BP_EXT_INTR_0, /* usExtIntrAdslDyingGasp */ ++ BP_NOT_DEFINED, /* usExtIntrHpna */ ++ BP_NOT_DEFINED, /* usCsHpna */ ++ BP_NOT_DEFINED, /* usAntInUseWireless */ ++ BP_NOT_DEFINED, /* usGpioSesBtnWireless */ ++ BP_NOT_DEFINED, /* usExtIntrSesBtnWireless */ ++ BP_NOT_DEFINED /* usGpioLedSesWireless */ ++}; ++ ++static PBOARD_PARAMETERS g_BoardParms[] = ++ {&g_bcm96345r, &g_bcm96345gw2, &g_bcm96345gw, &g_bcm96335r, &g_bcm96345r0, ++ &g_bcm96345rs, 0}; ++#endif ++ ++#if defined(_BCM96348_) || defined(CONFIG_BCM96348) ++ ++static BOARD_PARAMETERS g_bcm96348r = ++{ ++ "96348R", /* szBoardId */ ++ {{BP_ENET_INTERNAL_PHY, /* ucPhyType */ ++ 0x01, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x01, /* numSwitchPorts */ ++ BP_ENET_CONFIG_MDIO, /* usConfigType */ ++ BP_NOT_DEFINED}, /* usReverseMii */ ++ {BP_ENET_NO_PHY}}, /* ucPhyType */ ++ {{BP_VOIP_NO_DSP}, /* ucDspType */ ++ {BP_VOIP_NO_DSP}}, /* ucDspType */ ++ BP_MEMORY_8MB_1_CHIP, /* usSdramSize */ ++ BP_PSI_DEFAULT_SIZE, /* usPsiSize */ ++ BP_NOT_DEFINED, /* usGpioRj11InnerPair */ ++ BP_NOT_DEFINED, /* usGpioRj11OuterPair */ ++ BP_GPIO_7_AH, /* usGpioPressAndHoldReset */ ++ BP_NOT_DEFINED, /* usGpioPcmciaReset */ ++ BP_NOT_DEFINED, /* usGpioUartRts */ ++ BP_NOT_DEFINED, /* usGpioUartCts */ ++ BP_NOT_DEFINED, /* usGpioLedAdsl */ ++ BP_GPIO_2_AL, /* usGpioLedAdslFail */ ++ BP_NOT_DEFINED, /* usGpioLedWireless */ ++ BP_NOT_DEFINED, /* usGpioLedUsb */ ++ BP_NOT_DEFINED, /* usGpioLedHpna */ ++ BP_GPIO_3_AL, /* usGpioLedWanData */ ++ BP_GPIO_3_AL, /* usGpioLedPpp */ ++ BP_GPIO_4_AL, /* usGpioLedPppFail */ ++ BP_GPIO_0_AL, /* usGpioLedBlPowerOn */ ++ BP_NOT_DEFINED, /* usGpioLedBlAlarm */ ++ BP_GPIO_3_AL, /* usGpioLedBlResetCfg */ ++ BP_GPIO_1_AL, /* usGpioLedBlStop */ ++ BP_NOT_DEFINED, /* usExtIntrWireless */ ++ BP_HW_DEFINED, /* usExtIntrAdslDyingGasp */ ++ BP_NOT_DEFINED, /* usExtIntrHpna */ ++ BP_NOT_DEFINED, /* usCsHpna */ ++ BP_NOT_DEFINED, /* usAntInUseWireless */ ++ BP_NOT_DEFINED, /* usGpioSesBtnWireless */ ++ BP_NOT_DEFINED, /* usExtIntrSesBtnWireless */ ++ BP_NOT_DEFINED /* usGpioLedSesWireless */ ++}; ++ ++static BOARD_PARAMETERS g_bcm96348lv = ++{ ++ "96348LV", /* szBoardId */ ++ {{BP_ENET_INTERNAL_PHY, /* ucPhyType */ ++ 0x01, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x01, /* numSwitchPorts */ ++ BP_ENET_CONFIG_MDIO, /* usConfigType */ ++ BP_NOT_DEFINED}, /* usReverseMii */ ++ {BP_ENET_EXTERNAL_PHY, /* ucPhyType */ ++ 0x02, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_GPIO_5_AL, /* usGpioPhyReset */ ++ 0x01, /* numSwitchPorts */ ++ BP_ENET_CONFIG_MDIO, /* usConfigType */ ++ BP_NOT_DEFINED}}, /* usReverseMii */ ++ {{BP_VOIP_NO_DSP}, /* ucDspType */ ++ {BP_VOIP_NO_DSP}}, /* ucDspType */ ++ BP_MEMORY_16MB_2_CHIP, /* usSdramSize */ ++ BP_PSI_DEFAULT_SIZE, /* usPsiSize */ ++ BP_NOT_DEFINED, /* usGpioRj11InnerPair */ ++ BP_NOT_DEFINED, /* usGpioRj11OuterPair */ ++ BP_GPIO_7_AH, /* usGpioPressAndHoldReset */ ++ BP_NOT_DEFINED, /* usGpioPcmciaReset */ ++ BP_NOT_DEFINED, /* usGpioUartRts */ ++ BP_NOT_DEFINED, /* usGpioUartCts */ ++ BP_NOT_DEFINED, /* usGpioLedAdsl */ ++ BP_GPIO_2_AL, /* usGpioLedAdslFail */ ++ BP_NOT_DEFINED, /* usGpioLedWireless */ ++ BP_NOT_DEFINED, /* usGpioLedUsb */ ++ BP_NOT_DEFINED, /* usGpioLedHpna */ ++ BP_GPIO_3_AL, /* usGpioLedWanData */ ++ BP_GPIO_3_AL, /* usGpioLedPpp */ ++ BP_GPIO_4_AL, /* usGpioLedPppFail */ ++ BP_GPIO_0_AL, /* usGpioLedBlPowerOn */ ++ BP_NOT_DEFINED, /* usGpioLedBlAlarm */ ++ BP_GPIO_3_AL, /* usGpioLedBlResetCfg */ ++ BP_GPIO_1_AL, /* usGpioLedBlStop */ ++ BP_NOT_DEFINED, /* usExtIntrWireless */ ++ BP_NOT_DEFINED, /* usExtIntrAdslDyingGasp */ ++ BP_NOT_DEFINED, /* usExtIntrHpna */ ++ BP_NOT_DEFINED, /* usCsHpna */ ++ BP_NOT_DEFINED, /* usAntInUseWireless */ ++ BP_NOT_DEFINED, /* usGpioSesBtnWireless */ ++ BP_NOT_DEFINED, /* usExtIntrSesBtnWireless */ ++ BP_NOT_DEFINED /* usGpioLedSesWireless */ ++}; ++ ++static BOARD_PARAMETERS g_bcm96348gw = ++{ ++ "96348GW", /* szBoardId */ ++ {{BP_ENET_INTERNAL_PHY, /* ucPhyType */ ++ 0x01, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x01, /* numSwitchPorts */ ++ BP_ENET_CONFIG_MDIO, /* usConfigType */ ++ BP_NOT_DEFINED}, /* usReverseMii */ ++ {BP_ENET_EXTERNAL_SWITCH, /* ucPhyType */ ++ 0x00, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x03, /* numSwitchPorts */ ++ BP_ENET_CONFIG_SPI_SSB_0, /* usConfigType */ ++ BP_ENET_REVERSE_MII}}, /* usReverseMii */ ++ {{BP_VOIP_DSP, /* ucDspType */ ++ 0x00, /* ucDspAddress */ ++ BP_EXT_INTR_2, /* usExtIntrVoip */ ++ BP_GPIO_6_AH, /* usGpioVoipReset */ ++ BP_GPIO_34_AH, /* usGpioVoipIntr */ ++ BP_NOT_DEFINED, /* usGpioLedVoip */ ++ BP_CS_2}, /* usCsVoip */ ++ {BP_VOIP_NO_DSP}}, /* ucDspType */ ++ BP_MEMORY_16MB_2_CHIP, /* usSdramSize */ ++ BP_PSI_DEFAULT_SIZE, /* usPsiSize */ ++ BP_NOT_DEFINED, /* usGpioRj11InnerPair */ ++ BP_NOT_DEFINED, /* usGpioRj11OuterPair */ ++ BP_GPIO_33_AL, /* usGpioPressAndHoldReset */ ++ BP_NOT_DEFINED, /* usGpioPcmciaReset */ ++ BP_NOT_DEFINED, /* usGpioUartRts */ ++ BP_NOT_DEFINED, /* usGpioUartCts */ ++ BP_NOT_DEFINED, /* usGpioLedAdsl */ ++ BP_GPIO_2_AL, /* usGpioLedAdslFail */ ++ BP_NOT_DEFINED, /* usGpioLedWireless */ ++ BP_NOT_DEFINED, /* usGpioLedUsb */ ++ BP_NOT_DEFINED, /* usGpioLedHpna */ ++ BP_GPIO_3_AL, /* usGpioLedWanData */ ++ BP_GPIO_3_AL, /* usGpioLedPpp */ ++ BP_GPIO_4_AL, /* usGpioLedPppFail */ ++ BP_GPIO_0_AL, /* usGpioLedBlPowerOn */ ++ BP_NOT_DEFINED, /* usGpioLedBlAlarm */ ++ BP_GPIO_3_AL, /* usGpioLedBlResetCfg */ ++ BP_GPIO_1_AL, /* usGpioLedBlStop */ ++ BP_NOT_DEFINED, /* usExtIntrWireless */ ++ BP_HW_DEFINED, /* usExtIntrAdslDyingGasp */ ++ BP_NOT_DEFINED, /* usExtIntrHpna */ ++ BP_NOT_DEFINED, /* usCsHpna */ ++ BP_WLAN_ANT_MAIN, /* usAntInUseWireless */ ++ BP_NOT_DEFINED, /* BP_GPIO_35_AH, */ /* usGpioSesBtnWireless */ ++ BP_NOT_DEFINED, /* BP_EXT_INTR_3, */ /* usExtIntrSesBtnWireless */ ++ BP_NOT_DEFINED /* BP_GPIO_0_AL */ /* usGpioLedSesWireless */ ++}; ++ ++ ++static BOARD_PARAMETERS g_bcm96348gw_10 = ++{ ++ "96348GW-10", /* szBoardId */ ++ {{BP_ENET_INTERNAL_PHY, /* ucPhyType */ ++ 0x01, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x01, /* numSwitchPorts */ ++ BP_ENET_CONFIG_MDIO, /* usConfigType */ ++ BP_NOT_DEFINED}, /* usReverseMii */ ++ {BP_ENET_EXTERNAL_SWITCH, /* ucPhyType */ ++ 0x00, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x03, /* numSwitchPorts */ ++ BP_ENET_CONFIG_SPI_SSB_1, /* usConfigType */ ++ BP_ENET_REVERSE_MII}}, /* usReverseMii */ ++ {{BP_VOIP_DSP, /* ucDspType */ ++ 0x00, /* ucDspAddress */ ++ BP_EXT_INTR_2, /* usExtIntrVoip */ ++ BP_GPIO_6_AH, /* usGpioVoipReset */ ++ BP_GPIO_34_AH, /* usGpioVoipIntr */ ++ BP_NOT_DEFINED, /* usGpioLedVoip */ ++ BP_CS_2}, /* usCsVoip */ ++ {BP_VOIP_NO_DSP}}, /* ucDspType */ ++ BP_MEMORY_16MB_2_CHIP, /* usSdramSize */ ++ BP_PSI_DEFAULT_SIZE, /* usPsiSize */ ++ BP_NOT_DEFINED, /* usGpioRj11InnerPair */ ++ BP_NOT_DEFINED, /* usGpioRj11OuterPair */ ++ BP_GPIO_33_AL, /* usGpioPressAndHoldReset */ ++ BP_NOT_DEFINED, /* usGpioPcmciaReset */ ++ BP_NOT_DEFINED, /* usGpioUartRts */ ++ BP_NOT_DEFINED, /* usGpioUartCts */ ++ BP_NOT_DEFINED, /* usGpioLedAdsl */ ++ BP_GPIO_2_AL, /* usGpioLedAdslFail */ ++ BP_NOT_DEFINED, /* usGpioLedWireless */ ++ BP_NOT_DEFINED, /* usGpioLedUsb */ ++ BP_NOT_DEFINED, /* usGpioLedHpna */ ++ BP_GPIO_3_AL, /* usGpioLedWanData */ ++ BP_GPIO_3_AL, /* usGpioLedPpp */ ++ BP_GPIO_4_AL, /* usGpioLedPppFail */ ++ BP_GPIO_0_AL, /* usGpioLedBlPowerOn */ ++ BP_NOT_DEFINED, /* usGpioLedBlAlarm */ ++ BP_GPIO_3_AL, /* usGpioLedBlResetCfg */ ++ BP_GPIO_1_AL, /* usGpioLedBlStop */ ++ BP_NOT_DEFINED, /* usExtIntrWireless */ ++ BP_HW_DEFINED, /* usExtIntrAdslDyingGasp */ ++ BP_NOT_DEFINED, /* usExtIntrHpna */ ++ BP_NOT_DEFINED, /* usCsHpna */ ++ BP_WLAN_ANT_MAIN, /* usAntInUseWireless */ ++ BP_NOT_DEFINED, /* usGpioSesBtnWireless */ ++ BP_NOT_DEFINED, /* usExtIntrSesBtnWireless */ ++ BP_NOT_DEFINED /* usGpioLedSesWireless */ ++}; ++ ++static BOARD_PARAMETERS g_bcm96348gw_11 = ++{ ++ "96348GW-11", /* szBoardId */ ++ {{BP_ENET_NO_PHY}, /* ucPhyType */ ++ {BP_ENET_EXTERNAL_SWITCH, /* ucPhyType */ ++ 0x00, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x04, /* numSwitchPorts */ ++ BP_ENET_CONFIG_SPI_SSB_1, /* usConfigType */ ++ BP_ENET_REVERSE_MII}}, /* usReverseMii */ ++ {{BP_VOIP_NO_DSP}, /* ucDspType */ ++ {BP_VOIP_NO_DSP}}, /* ucDspType */ ++ BP_MEMORY_16MB_2_CHIP, /* usSdramSize */ ++ BP_PSI_DEFAULT_SIZE, /* usPsiSize */ ++ BP_NOT_DEFINED, /* usGpioRj11InnerPair */ ++ BP_NOT_DEFINED, /* usGpioRj11OuterPair */ ++ BP_GPIO_33_AL, /* usGpioPressAndHoldReset */ ++ BP_NOT_DEFINED, /* usGpioPcmciaReset */ ++ BP_NOT_DEFINED, /* usGpioUartRts */ ++ BP_NOT_DEFINED, /* usGpioUartCts */ ++ BP_NOT_DEFINED, /* usGpioLedAdsl */ ++ BP_GPIO_2_AL, /* usGpioLedAdslFail */ ++ BP_NOT_DEFINED, /* usGpioLedWireless */ ++ BP_NOT_DEFINED, /* usGpioLedUsb */ ++ BP_NOT_DEFINED, /* usGpioLedHpna */ ++ BP_GPIO_3_AL, /* usGpioLedWanData */ ++ BP_GPIO_3_AL, /* usGpioLedPpp */ ++ BP_GPIO_4_AL, /* usGpioLedPppFail */ ++ BP_GPIO_0_AL, /* usGpioLedBlPowerOn */ ++ BP_NOT_DEFINED, /* usGpioLedBlAlarm */ ++ BP_GPIO_3_AL, /* usGpioLedBlResetCfg */ ++ BP_GPIO_1_AL, /* usGpioLedBlStop */ ++ BP_NOT_DEFINED, /* usExtIntrWireless */ ++ BP_HW_DEFINED, /* usExtIntrAdslDyingGasp */ ++ BP_NOT_DEFINED, /* usExtIntrHpna */ ++ BP_NOT_DEFINED, /* usCsHpna */ ++ BP_NOT_DEFINED, /* usAntInUseWireless */ ++ BP_NOT_DEFINED, /* usGpioSesBtnWireless */ ++ BP_NOT_DEFINED, /* usExtIntrSesBtnWireless */ ++ BP_NOT_DEFINED /* usGpioLedSesWireless */ ++}; ++ ++static BOARD_PARAMETERS g_bcm96348sv = ++{ ++ "96348SV", /* szBoardId */ ++ {{BP_ENET_INTERNAL_PHY, /* ucPhyType */ ++ 0x01, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x01, /* numSwitchPorts */ ++ BP_ENET_CONFIG_MDIO, /* usConfigType */ ++ BP_NOT_DEFINED}, /* usReverseMii */ ++ {BP_ENET_EXTERNAL_PHY, /* ucPhyType */ ++ 0x1f, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x01, /* numSwitchPorts */ ++ BP_ENET_CONFIG_MDIO, /* usConfigType */ ++ BP_NOT_DEFINED}}, /* usReverseMii */ ++ {{BP_VOIP_NO_DSP}, /* ucDspType */ ++ {BP_VOIP_NO_DSP}}, /* ucDspType */ ++ BP_MEMORY_32MB_2_CHIP, /* usSdramSize */ ++ BP_PSI_DEFAULT_SIZE, /* usPsiSize */ ++ BP_NOT_DEFINED, /* usGpioRj11InnerPair */ ++ BP_NOT_DEFINED, /* usGpioRj11OuterPair */ ++ BP_NOT_DEFINED, /* usGpioPressAndHoldReset */ ++ BP_NOT_DEFINED, /* usGpioPcmciaReset */ ++ BP_NOT_DEFINED, /* usGpioUartRts */ ++ BP_NOT_DEFINED, /* usGpioUartCts */ ++ BP_NOT_DEFINED, /* usGpioLedAdsl */ ++ BP_NOT_DEFINED, /* usGpioLedAdslFail */ ++ BP_NOT_DEFINED, /* usGpioLedWireless */ ++ BP_NOT_DEFINED, /* usGpioLedUsb */ ++ BP_NOT_DEFINED, /* usGpioLedHpna */ ++ BP_NOT_DEFINED, /* usGpioLedWanData */ ++ BP_NOT_DEFINED, /* usGpioLedPpp */ ++ BP_NOT_DEFINED, /* usGpioLedPppFail */ ++ BP_NOT_DEFINED, /* usGpioLedBlPowerOn */ ++ BP_NOT_DEFINED, /* usGpioLedBlAlarm */ ++ BP_NOT_DEFINED, /* usGpioLedBlResetCfg */ ++ BP_NOT_DEFINED, /* usGpioLedBlStop */ ++ BP_NOT_DEFINED, /* usExtIntrWireless */ ++ BP_HW_DEFINED, /* usExtIntrAdslDyingGasp */ ++ BP_NOT_DEFINED, /* usExtIntrHpna */ ++ BP_NOT_DEFINED, /* usCsHpna */ ++ BP_NOT_DEFINED, /* usAntInUseWireless */ ++ BP_NOT_DEFINED, /* usGpioSesBtnWireless */ ++ BP_NOT_DEFINED, /* usExtIntrSesBtnWireless */ ++ BP_NOT_DEFINED /* usGpioLedSesWireless */ ++}; ++ ++ ++static BOARD_PARAMETERS g_bcm96348gw_dualDsp = ++{ ++ "96348GW-DualDSP", /* szBoardId */ ++ {{BP_ENET_INTERNAL_PHY, /* ucPhyType */ ++ 0x01, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x01, /* numSwitchPorts */ ++ BP_ENET_CONFIG_MDIO, /* usConfigType */ ++ BP_NOT_DEFINED}, /* usReverseMii */ ++ {BP_ENET_EXTERNAL_SWITCH, /* ucPhyType */ ++ 0x00, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x03, /* numSwitchPorts */ ++ BP_ENET_CONFIG_SPI_SSB_1, /* usConfigType */ ++ BP_ENET_REVERSE_MII}}, /* usReverseMii */ ++ {{BP_VOIP_DSP, /* ucDspType */ ++ 0x00, /* ucDspAddress */ ++ BP_EXT_INTR_2, /* usExtIntrVoip */ ++ BP_UNEQUIPPED, /* usGpioVoipReset */ ++ BP_GPIO_34_AH, /* usGpioVoipIntr */ ++ BP_NOT_DEFINED, /* usGpioLedVoip */ ++ BP_CS_2}, /* usCsVoip */ ++ {BP_VOIP_DSP, /* ucDspType */ ++ 0x01, /* ucDspAddress */ ++ BP_EXT_INTR_3, /* usExtIntrVoip */ ++ BP_UNEQUIPPED , /* usGpioVoipReset */ ++ BP_GPIO_35_AH, /* usGpioVoipIntr */ ++ BP_NOT_DEFINED, /* usGpioLedVoip */ ++ BP_CS_3}}, /* usCsVoip */ ++ BP_MEMORY_16MB_2_CHIP, /* usSdramSize */ ++ BP_PSI_DEFAULT_SIZE, /* usPsiSize */ ++ BP_NOT_DEFINED, /* usGpioRj11InnerPair */ ++ BP_NOT_DEFINED, /* usGpioRj11OuterPair */ ++ BP_GPIO_33_AL, /* usGpioPressAndHoldReset */ ++ BP_NOT_DEFINED, /* usGpioPcmciaReset */ ++ BP_NOT_DEFINED, /* usGpioUartRts */ ++ BP_NOT_DEFINED, /* usGpioUartCts */ ++ BP_NOT_DEFINED, /* usGpioLedAdsl */ ++ BP_GPIO_2_AL, /* usGpioLedAdslFail */ ++ BP_NOT_DEFINED, /* usGpioLedWireless */ ++ BP_NOT_DEFINED, /* usGpioLedUsb */ ++ BP_NOT_DEFINED, /* usGpioLedHpna */ ++ BP_GPIO_3_AL, /* usGpioLedWanData */ ++ BP_GPIO_3_AL, /* usGpioLedPpp */ ++ BP_GPIO_4_AL, /* usGpioLedPppFail */ ++ BP_GPIO_0_AL, /* usGpioLedBlPowerOn */ ++ BP_NOT_DEFINED, /* usGpioLedBlAlarm */ ++ BP_GPIO_3_AL, /* usGpioLedBlResetCfg */ ++ BP_GPIO_1_AL, /* usGpioLedBlStop */ ++ BP_NOT_DEFINED, /* usExtIntrWireless */ ++ BP_HW_DEFINED, /* usExtIntrAdslDyingGasp */ ++ BP_NOT_DEFINED, /* usExtIntrHpna */ ++ BP_NOT_DEFINED, /* usCsHpna */ ++ BP_WLAN_ANT_MAIN, /* usAntInUseWireless */ ++ BP_NOT_DEFINED, /* usGpioSesBtnWireless */ ++ BP_NOT_DEFINED, /* usExtIntrSesBtnWireless */ ++ BP_NOT_DEFINED /* usGpioLedSesWireless */ ++}; ++ ++ ++static BOARD_PARAMETERS g_bcmCustom_01 = ++{ ++ "BCMCUST_01", /* szBoardId */ ++ {{BP_ENET_INTERNAL_PHY, /* ucPhyType */ ++ 0x01, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x01, /* numSwitchPorts */ ++ BP_ENET_CONFIG_MDIO, /* usConfigType */ ++ BP_NOT_DEFINED}, /* usReverseMii */ ++ {BP_ENET_NO_PHY, /* ucPhyType */ ++ 0x00, /* ucPhyAddress */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSck */ ++ BP_NOT_DEFINED, /* usGpioPhySpiSs */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMosi */ ++ BP_NOT_DEFINED, /* usGpioPhySpiMiso */ ++ BP_NOT_DEFINED, /* usGpioPhyReset */ ++ 0x01, /* numSwitchPorts */ ++ BP_ENET_CONFIG_SPI_SSB_1, /* usConfigType */ ++ BP_ENET_REVERSE_MII}}, /* usReverseMii */ ++ {{BP_VOIP_DSP, /* ucDspType */ ++ 0x00, /* ucDspAddress */ ++ BP_EXT_INTR_2, /* usExtIntrVoip */ ++ BP_GPIO_36_AH, /* usGpioVoipReset */ ++ BP_GPIO_34_AL, /* usGpioVoipIntr */ ++ BP_NOT_DEFINED, /* usGpioLedVoip */ ++ BP_CS_2}, /* usCsVoip */ ++ {BP_VOIP_NO_DSP}}, /* ucDspType */ ++ BP_MEMORY_16MB_2_CHIP, /* usSdramSize */ ++ BP_PSI_DEFAULT_SIZE, /* usPsiSize */ ++ BP_NOT_DEFINED, /* usGpioRj11InnerPair */ ++ BP_NOT_DEFINED, /* usGpioRj11OuterPair */ ++ BP_GPIO_33_AL, /* usGpioPressAndHoldReset */ ++ BP_NOT_DEFINED, /* usGpioPcmciaReset */ ++ BP_NOT_DEFINED, /* usGpioUartRts */ ++ BP_NOT_DEFINED, /* usGpioUartCts */ ++ BP_NOT_DEFINED, /* usGpioLedAdsl */ ++ BP_GPIO_2_AL, /* usGpioLedAdslFail */ ++ BP_NOT_DEFINED, /* usGpioLedWireless */ ++ BP_NOT_DEFINED, /* usGpioLedUsb */ ++ BP_NOT_DEFINED, /* usGpioLedHpna */ ++ BP_GPIO_3_AL, /* usGpioLedWanData */ ++ BP_GPIO_3_AL, /* usGpioLedPpp */ ++ BP_GPIO_4_AL, /* usGpioLedPppFail */ ++ BP_GPIO_0_AL, /* usGpioLedBlPowerOn */ ++ BP_NOT_DEFINED, /* usGpioLedBlAlarm */ ++ BP_GPIO_3_AL, /* usGpioLedBlResetCfg */ ++ BP_GPIO_1_AL, /* usGpioLedBlStop */ ++ BP_NOT_DEFINED, /* usExtIntrWireless */ ++ BP_NOT_DEFINED, /* usExtIntrAdslDyingGasp */ ++ BP_NOT_DEFINED, /* usExtIntrHpna */ ++ BP_NOT_DEFINED, /* usCsHpna */ ++ BP_NOT_DEFINED, /* usAntInUseWireless */ ++ BP_NOT_DEFINED, /* usGpioSesBtnWireless */ ++ BP_NOT_DEFINED, /* usExtIntrSesBtnWireless */ ++ BP_NOT_DEFINED /* usGpioLedSesWireless */ ++}; ++ ++static PBOARD_PARAMETERS g_BoardParms[] = ++ {&g_bcm96348r, &g_bcm96348lv, &g_bcm96348gw, &g_bcm96348gw_10, ++ &g_bcm96348gw_11, &g_bcm96348sv, &g_bcm96348gw_dualDsp, ++ &g_bcmCustom_01, 0}; ++#endif ++ ++static PBOARD_PARAMETERS g_pCurrentBp = 0; ++ ++/************************************************************************** ++ * Name : bpstrcmp ++ * ++ * Description: String compare for this file so it does not depend on an OS. + * (Linux kernel and CFE share this source file.) ++ * ++ * Parameters : [IN] dest - destination string ++ * [IN] src - source string ++ * ++ * Returns : -1 - dest < src, 1 - dest > src, 0 dest == src ++ ***************************************************************************/ ++static int bpstrcmp(const char *dest,const char *src); ++static int bpstrcmp(const char *dest,const char *src) ++{ ++ while (*src && *dest) ++ { ++ if (*dest < *src) return -1; ++ if (*dest > *src) return 1; ++ dest++; ++ src++; ++ } ++ ++ if (*dest && !*src) return 1; ++ if (!*dest && *src) return -1; ++ return 0; ++} /* bpstrcmp */ ++ ++/************************************************************************** ++ * Name : BpGetVoipDspConfig ++ * ++ * Description: Gets the DSP configuration from the board parameter ++ * structure for a given DSP index. ++ * ++ * Parameters : [IN] dspNum - DSP index (number) ++ * ++ * Returns : Pointer to DSP configuration block if found/valid, NULL ++ * otherwise. ++ ***************************************************************************/ ++VOIP_DSP_INFO *BpGetVoipDspConfig( unsigned char dspNum ); ++VOIP_DSP_INFO *BpGetVoipDspConfig( unsigned char dspNum ) ++{ ++ VOIP_DSP_INFO *pDspConfig = 0; ++ int i; ++ ++ if( g_pCurrentBp ) ++ { ++ for( i = 0 ; i < BP_MAX_VOIP_DSP ; i++ ) ++ { ++ if( g_pCurrentBp->VoIPDspInfo[i].ucDspType != BP_VOIP_NO_DSP && ++ g_pCurrentBp->VoIPDspInfo[i].ucDspAddress == dspNum ) ++ { ++ pDspConfig = &g_pCurrentBp->VoIPDspInfo[i]; ++ break; ++ } ++ } ++ } ++ ++ return pDspConfig; ++} ++ ++ ++/************************************************************************** ++ * Name : BpSetBoardId ++ * ++ * Description: This function find the BOARD_PARAMETERS structure for the ++ * specified board id string and assigns it to a global, static ++ * variable. ++ * ++ * Parameters : [IN] pszBoardId - Board id string that is saved into NVRAM. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_FOUND - Error, board id input string does not ++ * have a board parameters configuration record. ++ ***************************************************************************/ ++int BpSetBoardId( char *pszBoardId ) ++{ ++ int nRet = BP_BOARD_ID_NOT_FOUND; ++ PBOARD_PARAMETERS *ppBp; ++ ++ for( ppBp = g_BoardParms; *ppBp; ppBp++ ) ++ { ++ if( !bpstrcmp((*ppBp)->szBoardId, pszBoardId) ) ++ { ++ g_pCurrentBp = *ppBp; ++ nRet = BP_SUCCESS; ++ break; ++ } ++ } ++ ++ return( nRet ); ++} /* BpSetBoardId */ ++ ++/************************************************************************** ++ * Name : BpGetBoardIds ++ * ++ * Description: This function returns all of the supported board id strings. ++ * ++ * Parameters : [OUT] pszBoardIds - Address of a buffer that the board id ++ * strings are returned in. Each id starts at BP_BOARD_ID_LEN ++ * boundary. ++ * [IN] nBoardIdsSize - Number of BP_BOARD_ID_LEN elements that ++ * were allocated in pszBoardIds. ++ * ++ * Returns : Number of board id strings returned. ++ ***************************************************************************/ ++int BpGetBoardIds( char *pszBoardIds, int nBoardIdsSize ) ++{ ++ PBOARD_PARAMETERS *ppBp; ++ int i; ++ char *src; ++ char *dest; ++ ++ for( i = 0, ppBp = g_BoardParms; *ppBp && nBoardIdsSize; ++ i++, ppBp++, nBoardIdsSize--, pszBoardIds += BP_BOARD_ID_LEN ) ++ { ++ dest = pszBoardIds; ++ src = (*ppBp)->szBoardId; ++ while( *src ) ++ *dest++ = *src++; ++ *dest = '\0'; ++ } ++ ++ return( i ); ++} /* BpGetBoardIds */ ++ ++/************************************************************************** ++ * Name : BpGetEthernetMacInfo ++ * ++ * Description: This function returns all of the supported board id strings. ++ * ++ * Parameters : [OUT] pEnetInfos - Address of an array of ETHERNET_MAC_INFO ++ * buffers. ++ * [IN] nNumEnetInfos - Number of ETHERNET_MAC_INFO elements that ++ * are pointed to by pEnetInfos. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ ***************************************************************************/ ++int BpGetEthernetMacInfo( PETHERNET_MAC_INFO pEnetInfos, int nNumEnetInfos ) ++{ ++ int i, nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ for( i = 0; i < nNumEnetInfos; i++, pEnetInfos++ ) ++ { ++ if( i < BP_MAX_ENET_MACS ) ++ { ++ unsigned char *src = (unsigned char *) ++ &g_pCurrentBp->EnetMacInfos[i]; ++ unsigned char *dest = (unsigned char *) pEnetInfos; ++ int len = sizeof(ETHERNET_MAC_INFO); ++ while( len-- ) ++ *dest++ = *src++; ++ } ++ else ++ pEnetInfos->ucPhyType = BP_ENET_NO_PHY; ++ } ++ ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ for( i = 0; i < nNumEnetInfos; i++, pEnetInfos++ ) ++ pEnetInfos->ucPhyType = BP_ENET_NO_PHY; ++ ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetEthernetMacInfo */ ++ ++/************************************************************************** ++ * Name : BpGetSdramSize ++ * ++ * Description: This function returns a constant that describees the board's ++ * SDRAM type and size. ++ * ++ * Parameters : [OUT] pulSdramSize - Address of short word that the SDRAM size ++ * is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ ***************************************************************************/ ++int BpGetSdramSize( unsigned long *pulSdramSize ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pulSdramSize = g_pCurrentBp->usSdramSize; ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ *pulSdramSize = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetSdramSize */ ++ ++/************************************************************************** ++ * Name : BpGetPsiSize ++ * ++ * Description: This function returns the persistent storage size in K bytes. ++ * ++ * Parameters : [OUT] pulPsiSize - Address of short word that the persistent ++ * storage size is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ ***************************************************************************/ ++int BpGetPsiSize( unsigned long *pulPsiSize ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pulPsiSize = g_pCurrentBp->usPsiSize; ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ *pulPsiSize = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetPsiSize */ ++ ++/************************************************************************** ++ * Name : BpGetRj11InnerOuterPairGpios ++ * ++ * Description: This function returns the GPIO pin assignments for changing ++ * between the RJ11 inner pair and RJ11 outer pair. ++ * ++ * Parameters : [OUT] pusInner - Address of short word that the RJ11 inner pair ++ * GPIO pin is returned in. ++ * [OUT] pusOuter - Address of short word that the RJ11 outer pair ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, values are returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetRj11InnerOuterPairGpios( unsigned short *pusInner, ++ unsigned short *pusOuter ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusInner = g_pCurrentBp->usGpioRj11InnerPair; ++ *pusOuter = g_pCurrentBp->usGpioRj11OuterPair; ++ ++ if( g_pCurrentBp->usGpioRj11InnerPair != BP_NOT_DEFINED && ++ g_pCurrentBp->usGpioRj11OuterPair != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusInner = *pusOuter = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetRj11InnerOuterPairGpios */ ++ ++/************************************************************************** ++ * Name : BpGetPressAndHoldResetGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the press ++ * and hold reset button. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the press and hold ++ * reset button GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetPressAndHoldResetGpio( unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusValue = g_pCurrentBp->usGpioPressAndHoldReset; ++ ++ if( g_pCurrentBp->usGpioPressAndHoldReset != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetPressAndHoldResetGpio */ ++ ++/************************************************************************** ++ * Name : BpGetVoipResetGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the VOIP ++ * Reset operation. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the VOIP reset ++ * GPIO pin is returned in. ++ * [IN] dspNum - Address of the DSP to query. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetVoipResetGpio( unsigned char dspNum, unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ VOIP_DSP_INFO *pDspInfo = BpGetVoipDspConfig( dspNum ); ++ ++ if( pDspInfo ) ++ { ++ *pusValue = pDspInfo->usGpioVoipReset; ++ ++ if( *pusValue != BP_NOT_DEFINED || ++ *pusValue == BP_UNEQUIPPED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_FOUND; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetVoipResetGpio */ ++ ++/************************************************************************** ++ * Name : BpGetVoipIntrGpio ++ * ++ * Description: This function returns the GPIO pin assignment for VoIP interrupt. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the VOIP interrupt ++ * GPIO pin is returned in. ++ * [IN] dspNum - Address of the DSP to query. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetVoipIntrGpio( unsigned char dspNum, unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ VOIP_DSP_INFO *pDspInfo = BpGetVoipDspConfig( dspNum ); ++ ++ if( pDspInfo ) ++ { ++ *pusValue = pDspInfo->usGpioVoipIntr; ++ ++ if( *pusValue != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_FOUND; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetVoipIntrGpio */ ++ ++/************************************************************************** ++ * Name : BpGetPcmciaResetGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the PCMCIA ++ * Reset operation. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the PCMCIA reset ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetPcmciaResetGpio( unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusValue = g_pCurrentBp->usGpioPcmciaReset; ++ ++ if( g_pCurrentBp->usGpioPcmciaReset != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetPcmciaResetGpio */ ++ ++/************************************************************************** ++ * Name : BpGetUartRtsCtsGpios ++ * ++ * Description: This function returns the GPIO pin assignments for RTS and CTS ++ * UART signals. ++ * ++ * Parameters : [OUT] pusRts - Address of short word that the UART RTS GPIO ++ * pin is returned in. ++ * [OUT] pusCts - Address of short word that the UART CTS GPIO ++ * pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, values are returned. ++ * BP_BOARD_ID_NOT_SET - Error, board id input string does not ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetRtsCtsUartGpios( unsigned short *pusRts, unsigned short *pusCts ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusRts = g_pCurrentBp->usGpioUartRts; ++ *pusCts = g_pCurrentBp->usGpioUartCts; ++ ++ if( g_pCurrentBp->usGpioUartRts != BP_NOT_DEFINED && ++ g_pCurrentBp->usGpioUartCts != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusRts = *pusCts = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetUartRtsCtsGpios */ ++ ++/************************************************************************** ++ * Name : BpGetAdslLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the ADSL ++ * LED. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the ADSL LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetAdslLedGpio( unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusValue = g_pCurrentBp->usGpioLedAdsl; ++ ++ if( g_pCurrentBp->usGpioLedAdsl != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetAdslLedGpio */ ++ ++/************************************************************************** ++ * Name : BpGetAdslFailLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the ADSL ++ * LED that is used when there is a DSL connection failure. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the ADSL LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetAdslFailLedGpio( unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusValue = g_pCurrentBp->usGpioLedAdslFail; ++ ++ if( g_pCurrentBp->usGpioLedAdslFail != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetAdslFailLedGpio */ ++ ++/************************************************************************** ++ * Name : BpGetWirelessLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the Wireless ++ * LED. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the Wireless LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetWirelessLedGpio( unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusValue = g_pCurrentBp->usGpioLedWireless; ++ ++ if( g_pCurrentBp->usGpioLedWireless != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetWirelessLedGpio */ ++ ++/************************************************************************** ++ * Name : BpGetWirelessAntInUse ++ * ++ * Description: This function returns the antennas in use for wireless ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the Wireless Antenna ++ * is in use. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetWirelessAntInUse( unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusValue = g_pCurrentBp->usAntInUseWireless; ++ ++ if( g_pCurrentBp->usAntInUseWireless != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetWirelessAntInUse */ ++ ++/************************************************************************** ++ * Name : BpGetWirelessSesBtnGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the Wireless ++ * Ses Button. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the Wireless LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetWirelessSesBtnGpio( unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusValue = g_pCurrentBp->usGpioSesBtnWireless; ++ ++ if( g_pCurrentBp->usGpioSesBtnWireless != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetWirelessSesBtnGpio */ ++ ++/************************************************************************** ++ * Name : BpGetWirelessSesExtIntr ++ * ++ * Description: This function returns the external interrupt number for the ++ * Wireless Ses Button. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the Wireless Ses ++ * external interrup is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetWirelessSesExtIntr( unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusValue = g_pCurrentBp->usExtIntrSesBtnWireless; ++ ++ if( g_pCurrentBp->usExtIntrSesBtnWireless != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++ ++} /* BpGetWirelessSesExtIntr */ ++ ++/************************************************************************** ++ * Name : BpGetWirelessSesLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the Wireless ++ * Ses Led. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the Wireless Ses ++ * Led GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetWirelessSesLedGpio( unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusValue = g_pCurrentBp->usGpioLedSesWireless; ++ ++ if( g_pCurrentBp->usGpioLedSesWireless != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++ ++} /* BpGetWirelessSesLedGpio */ ++ ++/************************************************************************** ++ * Name : BpGetUsbLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the USB ++ * LED. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the USB LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetUsbLedGpio( unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusValue = g_pCurrentBp->usGpioLedUsb; ++ ++ if( g_pCurrentBp->usGpioLedUsb != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetUsbLedGpio */ ++ ++/************************************************************************** ++ * Name : BpGetHpnaLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the HPNA ++ * LED. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the HPNA LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetHpnaLedGpio( unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusValue = g_pCurrentBp->usGpioLedHpna; ++ ++ if( g_pCurrentBp->usGpioLedHpna != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetHpnaLedGpio */ ++ ++/************************************************************************** ++ * Name : BpGetWanDataLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the WAN Data ++ * LED. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the WAN Data LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetWanDataLedGpio( unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusValue = g_pCurrentBp->usGpioLedWanData; ++ ++ if( g_pCurrentBp->usGpioLedWanData != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetWanDataLedGpio */ ++ ++/************************************************************************** ++ * Name : BpGetPppLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the PPP ++ * LED. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the PPP LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetPppLedGpio( unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusValue = g_pCurrentBp->usGpioLedPpp; ++ ++ if( g_pCurrentBp->usGpioLedPpp != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetPppLedGpio */ ++ ++/************************************************************************** ++ * Name : BpGetPppFailLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the PPP ++ * LED that is used when there is a PPP connection failure. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the PPP LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetPppFailLedGpio( unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusValue = g_pCurrentBp->usGpioLedPppFail; ++ ++ if( g_pCurrentBp->usGpioLedPppFail != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetPppFailLedGpio */ ++ ++/************************************************************************** ++ * Name : BpGetBootloaderPowerOnLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the power ++ * on LED that is set by the bootloader. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the alarm LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetBootloaderPowerOnLedGpio( unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusValue = g_pCurrentBp->usGpioLedBlPowerOn; ++ ++ if( g_pCurrentBp->usGpioLedBlPowerOn != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetBootloaderPowerOn */ ++ ++/************************************************************************** ++ * Name : BpGetBootloaderAlarmLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the alarm ++ * LED that is set by the bootloader. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the alarm LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetBootloaderAlarmLedGpio( unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusValue = g_pCurrentBp->usGpioLedBlAlarm; ++ ++ if( g_pCurrentBp->usGpioLedBlAlarm != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetBootloaderAlarmLedGpio */ ++ ++/************************************************************************** ++ * Name : BpGetBootloaderResetCfgLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the reset ++ * configuration LED that is set by the bootloader. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the reset ++ * configuration LED GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetBootloaderResetCfgLedGpio( unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusValue = g_pCurrentBp->usGpioLedBlResetCfg; ++ ++ if( g_pCurrentBp->usGpioLedBlResetCfg != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetBootloaderResetCfgLedGpio */ ++ ++/************************************************************************** ++ * Name : BpGetBootloaderStopLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the break ++ * into bootloader LED that is set by the bootloader. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the break into ++ * bootloader LED GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetBootloaderStopLedGpio( unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pusValue = g_pCurrentBp->usGpioLedBlStop; ++ ++ if( g_pCurrentBp->usGpioLedBlStop != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetBootloaderStopLedGpio */ ++ ++/************************************************************************** ++ * Name : BpGetVoipLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the VOIP ++ * LED. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the VOIP LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ * ++ * Note : The VoIP structure would allow for having one LED per DSP ++ * however, the board initialization function assumes only one ++ * LED per functionality (ie one LED for VoIP). Therefore in ++ * order to keep this tidy and simple we do not make usage of the ++ * one-LED-per-DSP function. Instead, we assume that the LED for ++ * VoIP is unique and associated with DSP 0 (always present on ++ * any VoIP platform). If changing this to a LED-per-DSP function ++ * then one need to update the board initialization driver in ++ * bcmdrivers\opensource\char\board\bcm963xx\impl1 ++ ***************************************************************************/ ++int BpGetVoipLedGpio( unsigned short *pusValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ VOIP_DSP_INFO *pDspInfo = BpGetVoipDspConfig( 0 ); ++ ++ if( pDspInfo ) ++ { ++ *pusValue = pDspInfo->usGpioLedVoip; ++ ++ if( *pusValue != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_FOUND; ++ } ++ } ++ else ++ { ++ *pusValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetVoipLedGpio */ ++ ++/************************************************************************** ++ * Name : BpGetWirelessExtIntr ++ * ++ * Description: This function returns the Wireless external interrupt number. ++ * ++ * Parameters : [OUT] pulValue - Address of short word that the wireless ++ * external interrupt number is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetWirelessExtIntr( unsigned long *pulValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pulValue = g_pCurrentBp->usExtIntrWireless; ++ ++ if( g_pCurrentBp->usExtIntrWireless != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pulValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetWirelessExtIntr */ ++ ++/************************************************************************** ++ * Name : BpGetAdslDyingGaspExtIntr ++ * ++ * Description: This function returns the ADSL Dying Gasp external interrupt ++ * number. ++ * ++ * Parameters : [OUT] pulValue - Address of short word that the ADSL Dying Gasp ++ * external interrupt number is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetAdslDyingGaspExtIntr( unsigned long *pulValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pulValue = g_pCurrentBp->usExtIntrAdslDyingGasp; ++ ++ if( g_pCurrentBp->usExtIntrAdslDyingGasp != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pulValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetAdslDyingGaspExtIntr */ ++ ++/************************************************************************** ++ * Name : BpGetVoipExtIntr ++ * ++ * Description: This function returns the VOIP external interrupt number. ++ * ++ * Parameters : [OUT] pulValue - Address of short word that the VOIP ++ * external interrupt number is returned in. ++ * [IN] dspNum - Address of the DSP to query. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetVoipExtIntr( unsigned char dspNum, unsigned long *pulValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ VOIP_DSP_INFO *pDspInfo = BpGetVoipDspConfig( dspNum ); ++ ++ if( pDspInfo ) ++ { ++ *pulValue = pDspInfo->usExtIntrVoip; ++ ++ if( *pulValue != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pulValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_FOUND; ++ } ++ } ++ else ++ { ++ *pulValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetVoipExtIntr */ ++ ++/************************************************************************** ++ * Name : BpGetHpnaExtIntr ++ * ++ * Description: This function returns the HPNA external interrupt number. ++ * ++ * Parameters : [OUT] pulValue - Address of short word that the HPNA ++ * external interrupt number is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetHpnaExtIntr( unsigned long *pulValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pulValue = g_pCurrentBp->usExtIntrHpna; ++ ++ if( g_pCurrentBp->usExtIntrHpna != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pulValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetHpnaExtIntr */ ++ ++/************************************************************************** ++ * Name : BpGetHpnaChipSelect ++ * ++ * Description: This function returns the HPNA chip select number. ++ * ++ * Parameters : [OUT] pulValue - Address of short word that the HPNA ++ * chip select number is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetHpnaChipSelect( unsigned long *pulValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ *pulValue = g_pCurrentBp->usCsHpna; ++ ++ if( g_pCurrentBp->usCsHpna != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pulValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetHpnaChipSelect */ ++ ++/************************************************************************** ++ * Name : BpGetVoipChipSelect ++ * ++ * Description: This function returns the VOIP chip select number. ++ * ++ * Parameters : [OUT] pulValue - Address of short word that the VOIP ++ * chip select number is returned in. ++ * [IN] dspNum - Address of the DSP to query. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetVoipChipSelect( unsigned char dspNum, unsigned long *pulValue ) ++{ ++ int nRet; ++ ++ if( g_pCurrentBp ) ++ { ++ VOIP_DSP_INFO *pDspInfo = BpGetVoipDspConfig( dspNum ); ++ ++ if( pDspInfo ) ++ { ++ *pulValue = pDspInfo->usCsVoip; ++ ++ if( *pulValue != BP_NOT_DEFINED ) ++ { ++ nRet = BP_SUCCESS; ++ } ++ else ++ { ++ nRet = BP_VALUE_NOT_DEFINED; ++ } ++ } ++ else ++ { ++ *pulValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_FOUND; ++ } ++ } ++ else ++ { ++ *pulValue = BP_NOT_DEFINED; ++ nRet = BP_BOARD_ID_NOT_SET; ++ } ++ ++ return( nRet ); ++} /* BpGetVoipChipSelect */ ++ +diff -urN linux-2.6.17/arch/mips/brcm-boards/bcm963xx/boardparms.h linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/boardparms.h +--- linux-2.6.17/arch/mips/brcm-boards/bcm963xx/boardparms.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/boardparms.h 2006-08-03 16:36:58.000000000 +0200 +@@ -0,0 +1,758 @@ ++/* ++<:copyright-gpl ++ ++ Copyright 2003 Broadcom Corp. All Rights Reserved. ++ ++ This program is free software; you can distribute it and/or modify it ++ under the terms of the GNU General Public License (Version 2) as ++ published by the Free Software Foundation. ++ ++ This program is distributed in the hope it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ ++:> ++*/ ++/************************************************************************** ++ * File Name : boardparms.h ++ * ++ * Description: This file contains definitions and function prototypes for ++ * the BCM63xx board parameter access functions. ++ * ++ * Updates : 07/14/2003 Created. ++ ***************************************************************************/ ++ ++#if !defined(_BOARDPARMS_H) ++#define _BOARDPARMS_H ++ ++/* Return codes. */ ++#define BP_SUCCESS 0 ++#define BP_BOARD_ID_NOT_FOUND 1 ++#define BP_VALUE_NOT_DEFINED 2 ++#define BP_BOARD_ID_NOT_SET 3 ++ ++/* Values for BpGetSdramSize. */ ++#define BP_MEMORY_8MB_1_CHIP 0 ++#define BP_MEMORY_16MB_1_CHIP 1 ++#define BP_MEMORY_32MB_1_CHIP 2 ++#define BP_MEMORY_64MB_2_CHIP 3 ++#define BP_MEMORY_32MB_2_CHIP 4 ++#define BP_MEMORY_16MB_2_CHIP 5 ++ ++/* Values for EthernetMacInfo PhyType. */ ++#define BP_ENET_NO_PHY 0 ++#define BP_ENET_INTERNAL_PHY 1 ++#define BP_ENET_EXTERNAL_PHY 2 ++#define BP_ENET_EXTERNAL_SWITCH 3 ++ ++/* Values for EthernetMacInfo Configuration type. */ ++#define BP_ENET_CONFIG_MDIO 0 /* Internal PHY, External PHY, Switch+(no GPIO, no SPI, no MDIO Pseudo phy */ ++#define BP_ENET_CONFIG_GPIO 1 /* Bcm96345GW board + Bcm5325M/E */ ++#define BP_ENET_CONFIG_MDIO_PSEUDO_PHY 2 /* Bcm96348GW board + Bcm5325E */ ++#define BP_ENET_CONFIG_SPI_SSB_0 3 /* Bcm96348GW board + Bcm5325M/E */ ++#define BP_ENET_CONFIG_SPI_SSB_1 4 /* Bcm96348GW board + Bcm5325M/E */ ++#define BP_ENET_CONFIG_SPI_SSB_2 5 /* Bcm96348GW board + Bcm5325M/E */ ++#define BP_ENET_CONFIG_SPI_SSB_3 6 /* Bcm96348GW board + Bcm5325M/E */ ++ ++/* Values for EthernetMacInfo Reverse MII. */ ++#define BP_ENET_NO_REVERSE_MII 0 ++#define BP_ENET_REVERSE_MII 1 ++ ++/* Values for VoIPDSPInfo DSPType. */ ++#define BP_VOIP_NO_DSP 0 ++#define BP_VOIP_DSP 1 ++ ++ ++/* Values for GPIO pin assignments (AH = Active High, AL = Active Low). */ ++#define BP_ACTIVE_MASK 0x8000 ++#define BP_ACTIVE_HIGH 0x0000 ++#define BP_ACTIVE_LOW 0x8000 ++#define BP_GPIO_0_AH (0 | BP_ACTIVE_HIGH) ++#define BP_GPIO_0_AL (0 | BP_ACTIVE_LOW) ++#define BP_GPIO_1_AH (1 | BP_ACTIVE_HIGH) ++#define BP_GPIO_1_AL (1 | BP_ACTIVE_LOW) ++#define BP_GPIO_2_AH (2 | BP_ACTIVE_HIGH) ++#define BP_GPIO_2_AL (2 | BP_ACTIVE_LOW) ++#define BP_GPIO_3_AH (3 | BP_ACTIVE_HIGH) ++#define BP_GPIO_3_AL (3 | BP_ACTIVE_LOW) ++#define BP_GPIO_4_AH (4 | BP_ACTIVE_HIGH) ++#define BP_GPIO_4_AL (4 | BP_ACTIVE_LOW) ++#define BP_GPIO_5_AH (5 | BP_ACTIVE_HIGH) ++#define BP_GPIO_5_AL (5 | BP_ACTIVE_LOW) ++#define BP_GPIO_6_AH (6 | BP_ACTIVE_HIGH) ++#define BP_GPIO_6_AL (6 | BP_ACTIVE_LOW) ++#define BP_GPIO_7_AH (7 | BP_ACTIVE_HIGH) ++#define BP_GPIO_7_AL (7 | BP_ACTIVE_LOW) ++#define BP_GPIO_8_AH (8 | BP_ACTIVE_HIGH) ++#define BP_GPIO_8_AL (8 | BP_ACTIVE_LOW) ++#define BP_GPIO_9_AH (9 | BP_ACTIVE_HIGH) ++#define BP_GPIO_9_AL (9 | BP_ACTIVE_LOW) ++#define BP_GPIO_10_AH (10 | BP_ACTIVE_HIGH) ++#define BP_GPIO_10_AL (10 | BP_ACTIVE_LOW) ++#define BP_GPIO_11_AH (11 | BP_ACTIVE_HIGH) ++#define BP_GPIO_11_AL (11 | BP_ACTIVE_LOW) ++#define BP_GPIO_12_AH (12 | BP_ACTIVE_HIGH) ++#define BP_GPIO_12_AL (12 | BP_ACTIVE_LOW) ++#define BP_GPIO_13_AH (13 | BP_ACTIVE_HIGH) ++#define BP_GPIO_13_AL (13 | BP_ACTIVE_LOW) ++#define BP_GPIO_14_AH (14 | BP_ACTIVE_HIGH) ++#define BP_GPIO_14_AL (14 | BP_ACTIVE_LOW) ++#define BP_GPIO_15_AH (15 | BP_ACTIVE_HIGH) ++#define BP_GPIO_15_AL (15 | BP_ACTIVE_LOW) ++#define BP_GPIO_16_AH (16 | BP_ACTIVE_HIGH) ++#define BP_GPIO_16_AL (16 | BP_ACTIVE_LOW) ++#define BP_GPIO_17_AH (17 | BP_ACTIVE_HIGH) ++#define BP_GPIO_17_AL (17 | BP_ACTIVE_LOW) ++#define BP_GPIO_18_AH (18 | BP_ACTIVE_HIGH) ++#define BP_GPIO_18_AL (18 | BP_ACTIVE_LOW) ++#define BP_GPIO_19_AH (19 | BP_ACTIVE_HIGH) ++#define BP_GPIO_19_AL (19 | BP_ACTIVE_LOW) ++#define BP_GPIO_20_AH (20 | BP_ACTIVE_HIGH) ++#define BP_GPIO_20_AL (20 | BP_ACTIVE_LOW) ++#define BP_GPIO_21_AH (21 | BP_ACTIVE_HIGH) ++#define BP_GPIO_21_AL (21 | BP_ACTIVE_LOW) ++#define BP_GPIO_22_AH (22 | BP_ACTIVE_HIGH) ++#define BP_GPIO_22_AL (22 | BP_ACTIVE_LOW) ++#define BP_GPIO_23_AH (23 | BP_ACTIVE_HIGH) ++#define BP_GPIO_23_AL (23 | BP_ACTIVE_LOW) ++#define BP_GPIO_24_AH (24 | BP_ACTIVE_HIGH) ++#define BP_GPIO_24_AL (24 | BP_ACTIVE_LOW) ++#define BP_GPIO_25_AH (25 | BP_ACTIVE_HIGH) ++#define BP_GPIO_25_AL (25 | BP_ACTIVE_LOW) ++#define BP_GPIO_26_AH (26 | BP_ACTIVE_HIGH) ++#define BP_GPIO_26_AL (26 | BP_ACTIVE_LOW) ++#define BP_GPIO_27_AH (27 | BP_ACTIVE_HIGH) ++#define BP_GPIO_27_AL (27 | BP_ACTIVE_LOW) ++#define BP_GPIO_28_AH (28 | BP_ACTIVE_HIGH) ++#define BP_GPIO_28_AL (28 | BP_ACTIVE_LOW) ++#define BP_GPIO_29_AH (29 | BP_ACTIVE_HIGH) ++#define BP_GPIO_29_AL (29 | BP_ACTIVE_LOW) ++#define BP_GPIO_30_AH (30 | BP_ACTIVE_HIGH) ++#define BP_GPIO_30_AL (30 | BP_ACTIVE_LOW) ++#define BP_GPIO_31_AH (31 | BP_ACTIVE_HIGH) ++#define BP_GPIO_31_AL (31 | BP_ACTIVE_LOW) ++#define BP_GPIO_32_AH (32 | BP_ACTIVE_HIGH) ++#define BP_GPIO_32_AL (32 | BP_ACTIVE_LOW) ++#define BP_GPIO_33_AH (33 | BP_ACTIVE_HIGH) ++#define BP_GPIO_33_AL (33 | BP_ACTIVE_LOW) ++#define BP_GPIO_34_AH (34 | BP_ACTIVE_HIGH) ++#define BP_GPIO_34_AL (34 | BP_ACTIVE_LOW) ++#define BP_GPIO_35_AH (35 | BP_ACTIVE_HIGH) ++#define BP_GPIO_35_AL (35 | BP_ACTIVE_LOW) ++#define BP_GPIO_36_AH (36 | BP_ACTIVE_HIGH) ++#define BP_GPIO_36_AL (36 | BP_ACTIVE_LOW) ++ ++/* Values for external interrupt assignments. */ ++#define BP_EXT_INTR_0 0 ++#define BP_EXT_INTR_1 1 ++#define BP_EXT_INTR_2 2 ++#define BP_EXT_INTR_3 3 ++ ++/* Values for chip select assignments. */ ++#define BP_CS_0 0 ++#define BP_CS_1 1 ++#define BP_CS_2 2 ++#define BP_CS_3 3 ++ ++/* Value for GPIO and external interrupt fields that are not used. */ ++#define BP_NOT_DEFINED 0xffff ++#define BP_HW_DEFINED 0xfff0 ++#define BP_UNEQUIPPED 0xfff1 ++ ++/* Maximum size of the board id string. */ ++#define BP_BOARD_ID_LEN 16 ++ ++/* Maximum number of Ethernet MACs. */ ++#define BP_MAX_ENET_MACS 2 ++ ++/* Maximum number of VoIP DSPs. */ ++#define BP_MAX_VOIP_DSP 2 ++ ++/* Wireless Antenna Settings. */ ++#define BP_WLAN_ANT_MAIN 0 ++#define BP_WLAN_ANT_AUX 1 ++#define BP_WLAN_ANT_BOTH 3 ++ ++#if !defined(__ASSEMBLER__) ++ ++/* Information about an Ethernet MAC. If ucPhyType is BP_ENET_NO_PHY, ++ * then the other fields are not valid. ++ */ ++typedef struct EthernetMacInfo ++{ ++ unsigned char ucPhyType; /* BP_ENET_xxx */ ++ unsigned char ucPhyAddress; /* 0 to 31 */ ++ unsigned short usGpioPhySpiSck; /* GPIO pin or not defined */ ++ unsigned short usGpioPhySpiSs; /* GPIO pin or not defined */ ++ unsigned short usGpioPhySpiMosi; /* GPIO pin or not defined */ ++ unsigned short usGpioPhySpiMiso; /* GPIO pin or not defined */ ++ unsigned short usGpioPhyReset; /* GPIO pin or not defined (96348LV) */ ++ unsigned short numSwitchPorts; /* Number of PHY ports */ ++ unsigned short usConfigType; /* Configuration type */ ++ unsigned short usReverseMii; /* Reverse MII */ ++} ETHERNET_MAC_INFO, *PETHERNET_MAC_INFO; ++ ++ ++/* Information about VoIP DSPs. If ucDspType is BP_VOIP_NO_DSP, ++ * then the other fields are not valid. ++ */ ++typedef struct VoIPDspInfo ++{ ++ unsigned char ucDspType; ++ unsigned char ucDspAddress; ++ unsigned short usExtIntrVoip; ++ unsigned short usGpioVoipReset; ++ unsigned short usGpioVoipIntr; ++ unsigned short usGpioLedVoip; ++ unsigned short usCsVoip; ++ ++} VOIP_DSP_INFO; ++ ++ ++/************************************************************************** ++ * Name : BpSetBoardId ++ * ++ * Description: This function find the BOARD_PARAMETERS structure for the ++ * specified board id string and assigns it to a global, static ++ * variable. ++ * ++ * Parameters : [IN] pszBoardId - Board id string that is saved into NVRAM. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_FOUND - Error, board id input string does not ++ * have a board parameters configuration record. ++ ***************************************************************************/ ++int BpSetBoardId( char *pszBoardId ); ++ ++/************************************************************************** ++ * Name : BpGetBoardIds ++ * ++ * Description: This function returns all of the supported board id strings. ++ * ++ * Parameters : [OUT] pszBoardIds - Address of a buffer that the board id ++ * strings are returned in. Each id starts at BP_BOARD_ID_LEN ++ * boundary. ++ * [IN] nBoardIdsSize - Number of BP_BOARD_ID_LEN elements that ++ * were allocated in pszBoardIds. ++ * ++ * Returns : Number of board id strings returned. ++ ***************************************************************************/ ++int BpGetBoardIds( char *pszBoardIds, int nBoardIdsSize ); ++ ++/************************************************************************** ++ * Name : BpGetEthernetMacInfo ++ * ++ * Description: This function returns all of the supported board id strings. ++ * ++ * Parameters : [OUT] pEnetInfos - Address of an array of ETHERNET_MAC_INFO ++ * buffers. ++ * [IN] nNumEnetInfos - Number of ETHERNET_MAC_INFO elements that ++ * are pointed to by pEnetInfos. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ ***************************************************************************/ ++int BpGetEthernetMacInfo( PETHERNET_MAC_INFO pEnetInfos, int nNumEnetInfos ); ++ ++/************************************************************************** ++ * Name : BpGetSdramSize ++ * ++ * Description: This function returns a constant that describees the board's ++ * SDRAM type and size. ++ * ++ * Parameters : [OUT] pulSdramSize - Address of short word that the SDRAM size ++ * is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ ***************************************************************************/ ++int BpGetSdramSize( unsigned long *pulSdramSize ); ++ ++/************************************************************************** ++ * Name : BpGetPsiSize ++ * ++ * Description: This function returns the persistent storage size in K bytes. ++ * ++ * Parameters : [OUT] pulPsiSize - Address of short word that the persistent ++ * storage size is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ ***************************************************************************/ ++int BpGetPsiSize( unsigned long *pulPsiSize ); ++ ++/************************************************************************** ++ * Name : BpGetRj11InnerOuterPairGpios ++ * ++ * Description: This function returns the GPIO pin assignments for changing ++ * between the RJ11 inner pair and RJ11 outer pair. ++ * ++ * Parameters : [OUT] pusInner - Address of short word that the RJ11 inner pair ++ * GPIO pin is returned in. ++ * [OUT] pusOuter - Address of short word that the RJ11 outer pair ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, values are returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetRj11InnerOuterPairGpios( unsigned short *pusInner, ++ unsigned short *pusOuter ); ++ ++/************************************************************************** ++ * Name : BpGetPressAndHoldResetGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the press ++ * and hold reset button. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the press and hold ++ * reset button GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetPressAndHoldResetGpio( unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetVoipResetGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the VOIP ++ * Reset operation. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the VOIP reset ++ * GPIO pin is returned in. ++ * [IN] dspNum - Address of the DSP to query. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetVoipResetGpio( unsigned char dspNum, unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetVoipIntrGpio ++ * ++ * Description: This function returns the GPIO pin assignment for VoIP interrupt. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the VOIP interrupt ++ * GPIO pin is returned in. ++ * [IN] dspNum - Address of the DSP to query. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetVoipIntrGpio( unsigned char dspNum, unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetPcmciaResetGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the PCMCIA ++ * Reset operation. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the PCMCIA reset ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetPcmciaResetGpio( unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetUartRtsCtsGpios ++ * ++ * Description: This function returns the GPIO pin assignments for RTS and CTS ++ * UART signals. ++ * ++ * Parameters : [OUT] pusRts - Address of short word that the UART RTS GPIO ++ * pin is returned in. ++ * [OUT] pusCts - Address of short word that the UART CTS GPIO ++ * pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, values are returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetRtsCtsUartGpios( unsigned short *pusRts, unsigned short *pusCts ); ++ ++/************************************************************************** ++ * Name : BpGetAdslLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the ADSL ++ * LED. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the ADSL LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetAdslLedGpio( unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetAdslFailLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the ADSL ++ * LED that is used when there is a DSL connection failure. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the ADSL LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetAdslFailLedGpio( unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetWirelessLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the Wireless ++ * LED. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the Wireless LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetWirelessLedGpio( unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetWirelessAntInUse ++ * ++ * Description: This function returns the antennas in use for wireless ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the Wireless Antenna ++ * is in use. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetWirelessAntInUse( unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetWirelessSesBtnGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the Wireless ++ * Ses Button. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the Wireless Ses ++ * Button GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetWirelessSesBtnGpio( unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetWirelessSesExtIntr ++ * ++ * Description: This function returns the external interrupt number for the ++ * Wireless Ses Button. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the Wireless Ses ++ * external interrup is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetWirelessSesExtIntr( unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetWirelessSesLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the Wireless ++ * Ses Led. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the Wireless Ses ++ * Led GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetWirelessSesLedGpio( unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetUsbLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the USB ++ * LED. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the USB LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetUsbLedGpio( unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetHpnaLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the HPNA ++ * LED. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the HPNA LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetHpnaLedGpio( unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetWanDataLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the WAN Data ++ * LED. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the WAN Data LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetWanDataLedGpio( unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetPppLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the PPP ++ * LED. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the PPP LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetPppLedGpio( unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetPppFailLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the PPP ++ * LED that is used when there is a PPP connection failure. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the PPP LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetPppFailLedGpio( unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetVoipLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the VOIP ++ * LED. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the VOIP LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetVoipLedGpio( unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetBootloaderPowerOnLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the power ++ * on LED that is set by the bootloader. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the alarm LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetBootloaderPowerOnLedGpio( unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetBootloaderAlarmLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the alarm ++ * LED that is set by the bootloader. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the alarm LED ++ * GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetBootloaderAlarmLedGpio( unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetBootloaderResetCfgLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the reset ++ * configuration LED that is set by the bootloader. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the reset ++ * configuration LED GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetBootloaderResetCfgLedGpio( unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetBootloaderStopLedGpio ++ * ++ * Description: This function returns the GPIO pin assignment for the break ++ * into bootloader LED that is set by the bootloader. ++ * ++ * Parameters : [OUT] pusValue - Address of short word that the break into ++ * bootloader LED GPIO pin is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetBootloaderStopLedGpio( unsigned short *pusValue ); ++ ++/************************************************************************** ++ * Name : BpGetWirelessExtIntr ++ * ++ * Description: This function returns the Wireless external interrupt number. ++ * ++ * Parameters : [OUT] pulValue - Address of short word that the wireless ++ * external interrupt number is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetWirelessExtIntr( unsigned long *pulValue ); ++ ++/************************************************************************** ++ * Name : BpGetAdslDyingGaspExtIntr ++ * ++ * Description: This function returns the ADSL Dying Gasp external interrupt ++ * number. ++ * ++ * Parameters : [OUT] pulValue - Address of short word that the ADSL Dying Gasp ++ * external interrupt number is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetAdslDyingGaspExtIntr( unsigned long *pulValue ); ++ ++/************************************************************************** ++ * Name : BpGetVoipExtIntr ++ * ++ * Description: This function returns the VOIP external interrupt number. ++ * ++ * Parameters : [OUT] pulValue - Address of short word that the VOIP ++ * external interrupt number is returned in. ++ * [IN] dspNum - Address of the DSP to query. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetVoipExtIntr( unsigned char dspNum, unsigned long *pulValue ); ++ ++/************************************************************************** ++ * Name : BpGetHpnaExtIntr ++ * ++ * Description: This function returns the HPNA external interrupt number. ++ * ++ * Parameters : [OUT] pulValue - Address of short word that the HPNA ++ * external interrupt number is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetHpnaExtIntr( unsigned long *pulValue ); ++ ++/************************************************************************** ++ * Name : BpGetHpnaChipSelect ++ * ++ * Description: This function returns the HPNA chip select number. ++ * ++ * Parameters : [OUT] pulValue - Address of short word that the HPNA ++ * chip select number is returned in. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetHpnaChipSelect( unsigned long *pulValue ); ++ ++/************************************************************************** ++ * Name : BpGetVoipChipSelect ++ * ++ * Description: This function returns the VOIP chip select number. ++ * ++ * Parameters : [OUT] pulValue - Address of short word that the VOIP ++ * chip select number is returned in. ++ * [IN] dspNum - Address of the DSP to query. ++ * ++ * Returns : BP_SUCCESS - Success, value is returned. ++ * BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called. ++ * BP_VALUE_NOT_DEFINED - At least one return value is not defined ++ * for the board. ++ ***************************************************************************/ ++int BpGetVoipChipSelect( unsigned char dspNum, unsigned long *pulValue ); ++ ++#endif /* __ASSEMBLER__ */ ++ ++#endif /* _BOARDPARMS_H */ ++ +diff -urN linux-2.6.17/arch/mips/brcm-boards/bcm963xx/cfiflash.c linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/cfiflash.c +--- linux-2.6.17/arch/mips/brcm-boards/bcm963xx/cfiflash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/cfiflash.c 2006-08-03 16:36:58.000000000 +0200 +@@ -0,0 +1,692 @@ ++/************************************************************************/ ++/* */ ++/* AMD CFI Enabled Flash Memory Drivers */ ++/* File name: CFIFLASH.C */ ++/* Revision: 1.0 5/07/98 */ ++/* */ ++/* Copyright (c) 1998 ADVANCED MICRO DEVICES, INC. All Rights Reserved. */ ++/* This software is unpublished and contains the trade secrets and */ ++/* confidential proprietary information of AMD. Unless otherwise */ ++/* provided in the Software Agreement associated herewith, it is */ ++/* licensed in confidence "AS IS" and is not to be reproduced in whole */ ++/* or part by any means except for backup. Use, duplication, or */ ++/* disclosure by the Government is subject to the restrictions in */ ++/* paragraph (b) (3) (B) of the Rights in Technical Data and Computer */ ++/* Software clause in DFAR 52.227-7013 (a) (Oct 1988). */ ++/* Software owned by */ ++/* Advanced Micro Devices, Inc., */ ++/* One AMD Place, */ ++/* P.O. Box 3453 */ ++/* Sunnyvale, CA 94088-3453. */ ++/************************************************************************/ ++/* This software constitutes a basic shell of source code for */ ++/* programming all AMD Flash components. AMD */ ++/* will not be responsible for misuse or illegal use of this */ ++/* software for devices not supported herein. AMD is providing */ ++/* this source code "AS IS" and will not be responsible for */ ++/* issues arising from incorrect user implementation of the */ ++/* source code herein. It is the user's responsibility to */ ++/* properly design-in this source code. */ ++/* */ ++/************************************************************************/ +#ifdef _CFE_ ++#include "lib_types.h" ++#include "lib_printf.h" ++#include "lib_string.h" ++#include "cfe_timer.h" ++#define printk printf ++#else // linux ++#include <linux/param.h> ++#include <linux/sched.h> ++#include <linux/timer.h> ++#endif ++ ++#include "cfiflash.h" ++ ++static int flash_wait(WORD sector, int offset, UINT16 data); ++static UINT16 flash_get_device_id(void); ++static int flash_get_cfi(struct cfi_query *query, UINT16 *cfi_struct, int flashFamily); ++static int flash_write(WORD sector, int offset, byte *buf, int nbytes); ++static void flash_command(int command, WORD sector, int offset, UINT16 data); ++ ++/*********************************************************************/ ++/* 'meminfo' should be a pointer, but most C compilers will not */ ++/* allocate static storage for a pointer without calling */ ++/* non-portable functions such as 'new'. We also want to avoid */ ++/* the overhead of passing this pointer for every driver call. */ ++/* Systems with limited heap space will need to do this. */ ++/*********************************************************************/ ++struct flashinfo meminfo; /* Flash information structure */ ++static int flashFamily = FLASH_UNDEFINED; ++static int totalSize = 0; ++static struct cfi_query query; ++ ++static UINT16 cfi_data_struct_29W160[] = { ++ 0x0020, 0x0049, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, ++ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, ++ 0x0051, 0x0052, 0x0059, 0x0002, 0x0000, 0x0040, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0027, 0x0036, 0x0000, 0x0000, 0x0004, ++ 0x0000, 0x000a, 0x0000, 0x0004, 0x0000, 0x0003, 0x0000, 0x0015, ++ 0x0002, 0x0000, 0x0000, 0x0000, 0x0004, 0x0000, 0x0000, 0x0040, ++ 0x0000, 0x0001, 0x0000, 0x0020, 0x0000, 0x0000, 0x0000, 0x0080, ++ 0x0000, 0x001e, 0x0000, 0x0000, 0x0001, 0xffff, 0xffff, 0xffff, ++ 0x0050, 0x0052, 0x0049, 0x0031, 0x0030, 0x0000, 0x0002, 0x0001, ++ 0x0001, 0x0004, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0x0002, ++ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, ++ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, ++ 0xffff, 0x0888, 0x252b, 0x8c84, 0x7dbc, 0xffff, 0xffff, 0xffff, ++ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, ++ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, ++ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff ++}; ++ ++ ++/*********************************************************************/ ++/* Init_flash is used to build a sector table from the information */ ++/* provided through the CFI query. This information is translated */ ++/* from erase_block information to base:offset information for each */ ++/* individual sector. This information is then stored in the meminfo */ ++/* structure, and used throughout the driver to access sector */ ++/* information. */ ++/* */ ++/* This is more efficient than deriving the sector base:offset */ ++/* information every time the memory map switches (since on the */ ++/* development platform can only map 64k at a time). If the entire */ ++/* flash memory array can be mapped in, then the addition static */ ++/* allocation for the meminfo structure can be eliminated, but the */ ++/* drivers will have to be re-written. */ ++/* */ ++/* The meminfo struct occupies 653 bytes of heap space, depending */ ++/* on the value of the define MAXSECTORS. Adjust to suit */ ++/* application */ ++/*********************************************************************/ ++byte flash_init(void) ++{ ++ int i=0, j=0, count=0; ++ int basecount=0L; ++ UINT16 device_id; ++ int flipCFIGeometry = FALSE; ++ ++ /* First, assume ++ * a single 8k sector for sector 0. This is to allow ++ * the system to perform memory mapping to the device, ++ * even though the actual physical layout is unknown. ++ * Once mapped in, the CFI query will produce all ++ * relevant information. ++ */ ++ meminfo.addr = 0L; ++ meminfo.areg = 0; ++ meminfo.nsect = 1; ++ meminfo.bank1start = 0; ++ meminfo.bank2start = 0; ++ ++ meminfo.sec[0].size = 8192; ++ meminfo.sec[0].base = 0x00000; ++ meminfo.sec[0].bank = 1; ++ ++ flash_command(FLASH_RESET, 0, 0, 0); ++ ++ device_id = flash_get_device_id(); ++ ++ switch (device_id) { ++ case ID_I28F160C3B: ++ case ID_I28F320C3B: ++ case ID_I28F160C3T: ++ case ID_I28F320C3T: ++ flashFamily = FLASH_INTEL; ++ break; ++ case ID_AM29DL800B: ++ case ID_AM29LV800B: ++ case ID_AM29LV400B: ++ case ID_AM29LV160B: ++ case ID_AM29LV320B: ++ case ID_MX29LV320AB: ++ case ID_AM29LV320MB: ++ case ID_AM29DL800T: ++ case ID_AM29LV800T: ++ case ID_AM29LV160T: ++ case ID_AM29LV320T: ++ case ID_MX29LV320AT: ++ case ID_AM29LV320MT: ++ flashFamily = FLASH_AMD; ++ break; ++ case ID_SST39VF1601: ++ case ID_SST39VF3201: ++ flashFamily = FLASH_SST; ++ break; ++ default: ++ printk("Flash memory not supported! Device id = %x\n", device_id); ++ return -1; ++ } ++ ++ if (flash_get_cfi(&query, 0, flashFamily) == -1) { ++ switch(device_id) { ++ case ID_AM29LV160T: ++ case ID_AM29LV160B: ++ flash_get_cfi(&query, cfi_data_struct_29W160, flashFamily); ++ break; ++ default: ++ printk("CFI data structure not found. Device id = %x\n", device_id); ++ return -1; ++ } ++ } ++ ++ // need to determine if it top or bottom boot here ++ switch (device_id) ++ { ++ case ID_AM29DL800B: ++ case ID_AM29LV800B: ++ case ID_AM29LV400B: ++ case ID_AM29LV160B: ++ case ID_AM29LV320B: ++ case ID_MX29LV320AB: ++ case ID_AM29LV320MB: ++ case ID_I28F160C3B: ++ case ID_I28F320C3B: ++ case ID_I28F160C3T: ++ case ID_I28F320C3T: ++ case ID_SST39VF1601: ++ case ID_SST39VF3201: ++ flipCFIGeometry = FALSE; ++ break; ++ case ID_AM29DL800T: ++ case ID_AM29LV800T: ++ case ID_AM29LV160T: ++ case ID_AM29LV320T: ++ case ID_MX29LV320AT: ++ case ID_AM29LV320MT: ++ flipCFIGeometry = TRUE; ++ break; ++ default: ++ printk("Flash memory not supported! Device id = %x\n", device_id); ++ return -1; ++ } ++ ++ count=0;basecount=0L; ++ ++ if (!flipCFIGeometry) ++ { ++ for (i=0; i<query.num_erase_blocks; i++) { ++ for(j=0; j<query.erase_block[i].num_sectors; j++) { ++ meminfo.sec[count].size = (int) query.erase_block[i].sector_size; ++ meminfo.sec[count].base = (int) basecount; ++ basecount += (int) query.erase_block[i].sector_size; ++ count++; ++ } ++ } ++ } ++ else ++ { ++ for (i = (query.num_erase_blocks - 1); i >= 0; i--) { ++ for(j=0; j<query.erase_block[i].num_sectors; j++) { ++ meminfo.sec[count].size = (int) query.erase_block[i].sector_size; ++ meminfo.sec[count].base = (int) basecount; ++ basecount += (int) query.erase_block[i].sector_size; ++ count++; ++ } ++ } ++ } ++ ++ meminfo.nsect = count; ++ totalSize = meminfo.sec[count-1].base + meminfo.sec[count-1].size; ++ return (0); ++} ++ ++/*********************************************************************/ ++/* Flash_sector_erase_int() is identical to flash_sector_erase(), */ ++/* except it will wait until the erase is completed before returning */ ++/* control to the calling function. This can be used in cases which */ ++/* require the program to hold until a sector is erased, without */ ++/* adding the wait check external to this function. */ ++/*********************************************************************/ ++byte flash_sector_erase_int(WORD sector) ++{ ++ int i; ++ ++ for( i = 0; i < 3; i++ ) { ++ flash_command(FLASH_SERASE, sector, 0, 0); ++ if (flash_wait(sector, 0, 0xffff) == STATUS_READY) ++ break; ++ } ++ ++ return(1); ++} ++ ++/*********************************************************************/ ++/* flash_read_buf() reads buffer of data from the specified */ ++/* offset from the sector parameter. */ ++/*********************************************************************/ ++int flash_read_buf(WORD sector, int offset, ++ byte *buffer, int numbytes) ++{ ++ byte *fwp; ++ ++ fwp = (byte *)flash_get_memptr(sector); ++ ++ while (numbytes) { ++ *buffer++ = *(fwp + offset); ++ numbytes--; ++ fwp++; ++ } ++ ++ return (1); ++} ++ ++/*********************************************************************/ ++/* flash_write_buf() utilizes */ ++/* the unlock bypass mode of the flash device. This can remove */ ++/* significant overhead from the bulk programming operation, and */ ++/* when programming bulk data a sizeable performance increase can be */ ++/* observed. */ ++/*********************************************************************/ ++int flash_write_buf(WORD sector, int offset, byte *buffer, int numbytes) ++{ ++ int ret = -1; ++ int i; ++ unsigned char *p = flash_get_memptr(sector) + offset; ++ ++ /* After writing the flash block, compare the contents to the source ++ * buffer. Try to write the sector successfully up to three times. ++ */ ++ for( i = 0; i < 3; i++ ) { ++ ret = flash_write(sector, offset, buffer, numbytes); ++ if( !memcmp( p, buffer, numbytes ) ) ++ break; ++ /* Erase and try again */ ++ flash_sector_erase_int(sector); ++ ret = -1; ++ } ++ ++ if( ret == -1 ) ++ printk( "Flash write error. Verify failed\n" ); ++ ++ return( ret ); ++} ++ ++/*********************************************************************/ ++/* Usefull funtion to return the number of sectors in the device. */ ++/* Can be used for functions which need to loop among all the */ ++/* sectors, or wish to know the number of the last sector. */ ++/*********************************************************************/ ++int flash_get_numsectors(void) ++{ ++ return meminfo.nsect; ++} ++ ++/*********************************************************************/ ++/* flash_get_sector_size() is provided for cases in which the size */ ++/* of a sector is required by a host application. The sector size */ ++/* (in bytes) is returned in the data location pointed to by the */ ++/* 'size' parameter. */ ++/*********************************************************************/ ++int flash_get_sector_size(WORD sector) ++{ ++ return meminfo.sec[sector].size; ++} ++ ++/*********************************************************************/ ++/* The purpose of flash_get_memptr() is to return a memory pointer */ ++/* which points to the beginning of memory space allocated for the */ ++/* flash. All function pointers are then referenced from this */ ++/* pointer. */ ++/* */ ++/* Different systems will implement this in different ways: */ ++/* possibilities include: */ ++/* - A direct memory pointer */ ++/* - A pointer to a memory map */ ++/* - A pointer to a hardware port from which the linear */ ++/* address is translated */ ++/* - Output of an MMU function / service */ ++/* */ ++/* Also note that this function expects the pointer to a specific */ ++/* sector of the device. This can be provided by dereferencing */ ++/* the pointer from a translated offset of the sector from a */ ++/* global base pointer (e.g. flashptr = base_pointer + sector_offset)*/ ++/* */ ++/* Important: Many AMD flash devices need both bank and or sector */ ++/* address bits to be correctly set (bank address bits are A18-A16, */ ++/* and sector address bits are A18-A12, or A12-A15). Flash parts */ ++/* which do not need these bits will ignore them, so it is safe to */ ++/* assume that every part will require these bits to be set. */ ++/*********************************************************************/ ++unsigned char *flash_get_memptr(WORD sector) ++{ ++ unsigned char *memptr = (unsigned char*)(FLASH_BASE_ADDR_REG + meminfo.sec[sector].base); ++ ++ return (memptr); ++} ++ ++/*********************************************************************/ ++/* The purpose of flash_get_blk() is to return a the block number */ ++/* for a given memory address. */ ++/*********************************************************************/ ++int flash_get_blk(int addr) ++{ ++ int blk_start, i; ++ int last_blk = flash_get_numsectors(); ++ int relative_addr = addr - (int) FLASH_BASE_ADDR_REG; ++ ++ for(blk_start=0, i=0; i < relative_addr && blk_start < last_blk; blk_start++) ++ i += flash_get_sector_size(blk_start); ++ ++ if( i > relative_addr ) ++ { ++ blk_start--; // last blk, dec by 1 ++ } ++ else ++ if( blk_start == last_blk ) ++ { ++ printk("Address is too big.\n"); ++ blk_start = -1; ++ } ++ ++ return( blk_start ); ++} ++ ++/************************************************************************/ ++/* The purpose of flash_get_total_size() is to return the total size of */ ++/* the flash */ ++/************************************************************************/ ++int flash_get_total_size() ++{ ++ return totalSize; ++} ++ ++/*********************************************************************/ ++/* Flash_command() is the main driver function. It performs */ ++/* every possible command available to AMD B revision */ ++/* flash parts. Note that this command is not used directly, but */ ++/* rather called through the API wrapper functions provided below. */ ++/*********************************************************************/ ++static void flash_command(int command, WORD sector, int offset, UINT16 data) ++{ ++ volatile UINT16 *flashptr; ++ volatile UINT16 *flashbase; ++ ++ flashptr = (UINT16 *) flash_get_memptr(sector); ++ flashbase = (UINT16 *) flash_get_memptr(0); ++ ++ switch (flashFamily) { ++ case FLASH_UNDEFINED: ++ /* These commands should work for AMD, Intel and SST flashes */ ++ switch (command) { ++ case FLASH_RESET: ++ flashptr[0] = 0xF0; ++ flashptr[0] = 0xFF; ++ break; ++ case FLASH_READ_ID: ++ flashptr[0x5555] = 0xAA; /* unlock 1 */ ++ flashptr[0x2AAA] = 0x55; /* unlock 2 */ ++ flashptr[0x5555] = 0x90; ++ break; ++ default: ++ break; ++ } ++ break; ++ case FLASH_AMD: ++ switch (command) { ++ case FLASH_RESET: ++ flashptr[0] = 0xF0; ++ break; ++ case FLASH_READ_ID: ++ flashptr[0x555] = 0xAA; /* unlock 1 */ ++ flashptr[0x2AA] = 0x55; /* unlock 2 */ ++ flashptr[0x555] = 0x90; ++ break; ++ case FLASH_CFIQUERY: ++ flashptr[0x55] = 0x98; ++ break; ++ case FLASH_UB: ++ flashptr[0x555] = 0xAA; /* unlock 1 */ ++ flashptr[0x2AA] = 0x55; /* unlock 2 */ ++ flashptr[0x555] = 0x20; ++ break; ++ case FLASH_PROG: ++ flashptr[0] = 0xA0; ++ flashptr[offset/2] = data; ++ break; ++ case FLASH_UBRESET: ++ flashptr[0] = 0x90; ++ flashptr[0] = 0x00; ++ break; ++ case FLASH_SERASE: ++ flashptr[0x555] = 0xAA; /* unlock 1 */ ++ flashptr[0x2AA] = 0x55; /* unlock 2 */ ++ flashptr[0x555] = 0x80; ++ flashptr[0x555] = 0xAA; ++ flashptr[0x2AA] = 0x55; ++ flashptr[0] = 0x30; ++ break; ++ default: ++ break; ++ } ++ break; ++ case FLASH_INTEL: ++ switch (command) { ++ case FLASH_RESET: ++ flashptr[0] = 0xFF; ++ break; ++ case FLASH_READ_ID: ++ flashptr[0] = 0x90; ++ break; ++ case FLASH_CFIQUERY: ++ flashptr[0] = 0x98; ++ break; ++ case FLASH_PROG: ++ flashptr[0] = 0x40; ++ flashptr[offset/2] = data; ++ break; ++ case FLASH_SERASE: ++ flashptr[0] = 0x60; ++ flashptr[0] = 0xD0; ++ flashptr[0] = 0x20; ++ flashptr[0] = 0xD0; ++ break; ++ default: ++ break; ++ } ++ break; ++ case FLASH_SST: ++ switch (command) { ++ case FLASH_RESET: ++ flashbase[0x5555] = 0xAA; /* unlock 1 */ ++ flashbase[0x2AAA] = 0x55; /* unlock 2 */ ++ flashbase[0x5555] = 0xf0; ++ break; ++ case FLASH_READ_ID: ++ flashbase[0x5555] = 0xAA; /* unlock 1 */ ++ flashbase[0x2AAA] = 0x55; /* unlock 2 */ ++ flashbase[0x5555] = 0x90; ++ break; ++ case FLASH_CFIQUERY: ++ flashbase[0x5555] = 0xAA; /* unlock 1 */ ++ flashbase[0x2AAA] = 0x55; /* unlock 2 */ ++ flashbase[0x5555] = 0x98; ++ break; ++ case FLASH_UB: ++ break; ++ case FLASH_PROG: ++ flashbase[0x5555] = 0xAA; /* unlock 1 */ ++ flashbase[0x2AAA] = 0x55; /* unlock 2 */ ++ flashbase[0x5555] = 0xa0; ++ flashptr[offset/2] = data; ++ break; ++ case FLASH_UBRESET: ++ break; ++ case FLASH_SERASE: ++ flashbase[0x5555] = 0xAA; /* unlock 1 */ ++ flashbase[0x2AAA] = 0x55; /* unlock 2 */ ++ flashbase[0x5555] = 0x80; ++ flashbase[0x5555] = 0xAA; ++ flashbase[0x2AAA] = 0x55; ++ flashptr[0] = 0x30; ++ break; ++ default: ++ break; ++ } ++ break; ++ default: ++ break; ++ } ++} ++ ++/*********************************************************************/ ++/* flash_write extends the functionality of flash_program() by */ ++/* providing an faster way to program multiple data words, without */ ++/* needing the function overhead of looping algorithms which */ ++/* program word by word. This function utilizes fast pointers */ ++/* to quickly loop through bulk data. */ ++/*********************************************************************/ ++static int flash_write(WORD sector, int offset, byte *buf, int nbytes) ++{ ++ UINT16 *src; ++ src = (UINT16 *)buf; ++ ++ if ((nbytes | offset) & 1) { ++ return -1; ++ } ++ ++ flash_command(FLASH_UB, 0, 0, 0); ++ while (nbytes > 0) { ++ flash_command(FLASH_PROG, sector, offset, *src); ++ if (flash_wait(sector, offset, *src) != STATUS_READY) ++ break; ++ offset +=2; ++ nbytes -=2; ++ src++; ++ } ++ flash_command(FLASH_UBRESET, 0, 0, 0); ++ ++ return (byte*)src - buf; ++} ++ ++/*********************************************************************/ ++/* flash_wait utilizes the DQ6, DQ5, and DQ2 polling algorithms */ ++/* described in the flash data book. It can quickly ascertain the */ ++/* operational status of the flash device, and return an */ ++/* appropriate status code (defined in flash.h) */ ++/*********************************************************************/ ++static int flash_wait(WORD sector, int offset, UINT16 data) ++{ ++ volatile UINT16 *flashptr; /* flash window */ ++ UINT16 d1; ++ ++ flashptr = (UINT16 *) flash_get_memptr(sector); ++ ++ if (flashFamily == FLASH_AMD || flashFamily == FLASH_SST) { ++#if defined(_BCM96338_) || defined(CONFIG_BCM96338) ++ do { ++ d1 = flashptr[offset/2]; ++ if (d1 == data) ++ return STATUS_READY; ++ } while (!(d1 & 0x20)); ++ ++ d1 = flashptr[offset/2]; ++ ++ if (d1 != data) { ++ flash_command(FLASH_RESET, 0, 0, 0); ++ return STATUS_TIMEOUT; ++ } ++#else ++ do { ++ d1 = *flashptr; /* read data */ ++ d1 ^= *flashptr; /* read it again and see what toggled */ ++ if (d1 == 0) /* no toggles, nothing's happening */ ++ return STATUS_READY; ++ } while (!(d1 & 0x20)); ++ ++ d1 = *flashptr; /* read data */ ++ d1 ^= *flashptr; /* read it again and see what toggled */ ++ ++ if (d1 != 0) { ++ flash_command(FLASH_RESET, 0, 0, 0); ++ return STATUS_TIMEOUT; ++ } ++#endif ++ } else if (flashFamily == FLASH_INTEL) { ++ flashptr[0] = 0x70; ++ /* Wait for completion */ ++ while(!(*flashptr & 0x80)); ++ if (*flashptr & 0x30) { ++ flashptr[0] = 0x50; ++ flash_command(FLASH_RESET, 0, 0, 0); ++ return STATUS_TIMEOUT; ++ } ++ flashptr[0] = 0x50; ++ flash_command(FLASH_RESET, 0, 0, 0); ++ } ++ ++ return STATUS_READY; ++} ++ ++/*********************************************************************/ ++/* flash_get_device_id() will perform an autoselect sequence on the */ ++/* flash device, and return the device id of the component. */ ++/* This function automatically resets to read mode. */ ++/*********************************************************************/ ++static UINT16 flash_get_device_id() ++{ ++ volatile UINT16 *fwp; /* flash window */ ++ UINT16 answer; ++ ++ fwp = (UINT16 *)flash_get_memptr(0); ++ ++ flash_command(FLASH_READ_ID, 0, 0, 0); ++ answer = *(fwp + 1); ++ if (answer == ID_AM29LV320M) { ++ answer = *(fwp + 0xe); ++ answer = *(fwp + 0xf); ++ } ++ ++ flash_command(FLASH_RESET, 0, 0, 0); ++ return( (UINT16) answer ); ++} ++ ++/*********************************************************************/ ++/* flash_get_cfi() is the main CFI workhorse function. Due to it's */ ++/* complexity and size it need only be called once upon */ ++/* initializing the flash system. Once it is called, all operations */ ++/* are performed by looking at the meminfo structure. */ ++/* All possible care was made to make this algorithm as efficient as */ ++/* possible. 90% of all operations are memory reads, and all */ ++/* calculations are done using bit-shifts when possible */ ++/*********************************************************************/ ++static int flash_get_cfi(struct cfi_query *query, UINT16 *cfi_struct, int flashFamily) ++{ ++ volatile UINT16 *fwp; /* flash window */ ++ int i=0; ++ ++ flash_command(FLASH_CFIQUERY, 0, 0, 0); ++ ++ if (cfi_struct == 0) ++ fwp = (UINT16 *)flash_get_memptr(0); ++ else ++ fwp = cfi_struct; ++ ++ /* Initial house-cleaning */ ++ for(i=0; i < 8; i++) { ++ query->erase_block[i].sector_size = 0; ++ query->erase_block[i].num_sectors = 0; ++ } ++ ++ /* If not 'QRY', then we dont have a CFI enabled device in the socket */ ++ if( fwp[0x10] != 'Q' && ++ fwp[0x11] != 'R' && ++ fwp[0x12] != 'Y') { ++ flash_command(FLASH_RESET, 0, 0, 0); ++ return(-1); ++ } ++ ++ query->num_erase_blocks = fwp[0x2C]; ++ if(flashFamily == FLASH_SST) ++ query->num_erase_blocks = 1; ++ ++ for(i=0; i < query->num_erase_blocks; i++) { ++ query->erase_block[i].num_sectors = fwp[(0x2D+(4*i))] + (fwp[0x2E + (4*i)] << 8); ++ query->erase_block[i].num_sectors++; ++ query->erase_block[i].sector_size = 256 * (256 * fwp[(0x30+(4*i))] + fwp[(0x2F+(4*i))]); ++ } ++ ++ flash_command(FLASH_RESET, 0, 0, 0); ++ return(1); ++} +diff -urN linux-2.6.17/arch/mips/brcm-boards/bcm963xx/cfiflash.h linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/cfiflash.h +--- linux-2.6.17/arch/mips/brcm-boards/bcm963xx/cfiflash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/cfiflash.h 2006-08-03 16:36:58.000000000 +0200 +@@ -0,0 +1,142 @@ ++/************************************************************************/ ++/* */ ++/* AMD CFI Enabled Flash Memory Drivers */ ++/* File name: CFIFLASH.H */ ++/* Revision: 1.0 5/07/98 */ ++/* */ ++/* Copyright (c) 1998 ADVANCED MICRO DEVICES, INC. All Rights Reserved. */ ++/* This software is unpublished and contains the trade secrets and */ ++/* confidential proprietary information of AMD. Unless otherwise */ ++/* provided in the Software Agreement associated herewith, it is */ ++/* licensed in confidence "AS IS" and is not to be reproduced in whole */ ++/* or part by any means except for backup. Use, duplication, or */ ++/* disclosure by the Government is subject to the restrictions in */ ++/* paragraph (b) (3) (B) of the Rights in Technical Data and Computer */ ++/* Software clause in DFAR 52.227-7013 (a) (Oct 1988). */ ++/* Software owned by */ ++/* Advanced Micro Devices, Inc., */ ++/* One AMD Place, */ ++/* P.O. Box 3453 */ ++/* Sunnyvale, CA 94088-3453. */ ++/************************************************************************/ ++/* This software constitutes a basic shell of source code for */ ++/* programming all AMD Flash components. AMD */ ++/* will not be responsible for misuse or illegal use of this */ ++/* software for devices not supported herein. AMD is providing */ ++/* this source code "AS IS" and will not be responsible for */ ++/* issues arising from incorrect user implementation of the */ ++/* source code herein. It is the user's responsibility to */ ++/* properly design-in this source code. */ ++/* */ ++/************************************************************************/ ++#ifndef _CFIFLASH_H ++#define _CFIFLASH_H ++ ++/* include board/CPU specific definitions */ ++#include "bcmtypes.h" ++#include "board.h" ++ ++#define FLASH_BASE_ADDR_REG FLASH_BASE ++ ++#ifndef NULL ++#define NULL 0 ++#endif ++ ++#define MAXSECTORS 1024 /* maximum number of sectors supported */ ++ ++/* A structure for identifying a flash part. There is one for each ++ * of the flash part definitions. We need to keep track of the ++ * sector organization, the address register used, and the size ++ * of the sectors. ++ */ ++struct flashinfo { ++ char *name; /* "Am29DL800T", etc. */ ++ unsigned long addr; /* physical address, once translated */ ++ int areg; /* Can be set to zero for all parts */ ++ int nsect; /* # of sectors -- 19 in LV, 22 in DL */ ++ int bank1start; /* first sector # in bank 1 */ ++ int bank2start; /* first sector # in bank 2, if DL part */ ++ struct { ++ long size; /* # of bytes in this sector */ ++ long base; /* offset from beginning of device */ ++ int bank; /* 1 or 2 for DL; 1 for LV */ ++ } sec[MAXSECTORS]; /* per-sector info */ ++}; ++ ++/* ++ * This structure holds all CFI query information as defined ++ * in the JEDEC standard. All information up to ++ * primary_extended_query is standard among all manufactures ++ * with CFI enabled devices. ++ */ ++ ++struct cfi_query { ++ int num_erase_blocks; /* Number of sector defs. */ ++ struct { ++ unsigned long sector_size; /* byte size of sector */ ++ int num_sectors; /* Num sectors of this size */ ++ } erase_block[8]; /* Max of 256, but 8 is good */ ++}; ++ ++/* Standard Boolean declarations */ ++#define TRUE 1 ++#define FALSE 0 ++ ++/* Define different type of flash */ ++#define FLASH_UNDEFINED 0 ++#define FLASH_AMD 1 ++#define FLASH_INTEL 2 ++#define FLASH_SST 3 ++ ++/* Command codes for the flash_command routine */ ++#define FLASH_RESET 0 /* reset to read mode */ ++#define FLASH_READ_ID 1 /* read device ID */ ++#define FLASH_CFIQUERY 2 /* CFI query */ ++#define FLASH_UB 3 /* go into unlock bypass mode */ ++#define FLASH_PROG 4 /* program a word */ ++#define FLASH_UBRESET 5 /* reset to read mode from unlock bypass mode */ ++#define FLASH_SERASE 6 /* sector erase */ ++ ++/* Return codes from flash_status */ ++#define STATUS_READY 0 /* ready for action */ ++#define STATUS_TIMEOUT 1 /* operation timed out */ ++ ++/* A list of AMD compatible device ID's - add others as needed */ ++#define ID_AM29DL800T 0x224A ++#define ID_AM29DL800B 0x22CB ++#define ID_AM29LV800T 0x22DA ++#define ID_AM29LV800B 0x225B ++#define ID_AM29LV400B 0x22BA ++ ++#define ID_AM29LV160B 0x2249 ++#define ID_AM29LV160T 0x22C4 ++ ++#define ID_AM29LV320T 0x22F6 ++#define ID_MX29LV320AT 0x22A7 ++#define ID_AM29LV320B 0x22F9 ++#define ID_MX29LV320AB 0x22A8 ++ ++#define ID_AM29LV320M 0x227E ++#define ID_AM29LV320MB 0x2200 ++#define ID_AM29LV320MT 0x2201 ++ ++#define ID_SST39VF1601 0x234B ++#define ID_SST39VF3201 0x235B ++ ++/* A list of Intel compatible device ID's - add others as needed */ ++#define ID_I28F160C3T 0x88C2 ++#define ID_I28F160C3B 0x88C3 ++#define ID_I28F320C3T 0x88C4 ++#define ID_I28F320C3B 0x88C5 ++ ++extern byte flash_init(void); ++extern int flash_write_buf(WORD sector, int offset, byte *buffer, int numbytes); ++extern int flash_read_buf(WORD sector, int offset, byte *buffer, int numbytes); ++extern byte flash_sector_erase_int(WORD sector); ++extern int flash_get_numsectors(void); ++extern int flash_get_sector_size(WORD sector); ++extern int flash_get_total_size(void); ++extern unsigned char *flash_get_memptr(WORD sector); ++extern int flash_get_blk(int addr); ++ ++#endif +diff -urN linux-2.6.17/arch/mips/brcm-boards/bcm963xx/irq.c linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/irq.c +--- linux-2.6.17/arch/mips/brcm-boards/bcm963xx/irq.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/irq.c 2006-08-03 16:36:58.000000000 +0200 +@@ -0,0 +1,299 @@ ++/* ++<:copyright-gpl ++ Copyright 2002 Broadcom Corp. All Rights Reserved. ++ ++ This program is free software; you can distribute it and/or modify it ++ under the terms of the GNU General Public License (Version 2) as ++ published by the Free Software Foundation. ++ ++ This program is distributed in the hope it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++:> ++*/ ++/* ++ * Interrupt control functions for Broadcom 963xx MIPS boards ++ */ ++ ++#include <asm/atomic.h> ++ ++#include <linux/delay.h> ++#include <linux/init.h> ++#include <linux/ioport.h> ++#include <linux/irq.h> ++#include <linux/interrupt.h> ++#include <linux/kernel.h> ++#include <linux/slab.h> ++#include <linux/module.h> ++#include <linux/spinlock.h> ++ ++#include <asm/irq.h> ++#include <asm/mipsregs.h> ++#include <asm/addrspace.h> ++#include <asm/signal.h> ++#include <bcm_map_part.h> ++#include <bcm_intr.h> ++ ++static DEFINE_SPINLOCK(irq_lock); ++ ++static void irq_dispatch_int(struct pt_regs *regs) ++{ ++ unsigned int pendingIrqs; ++ static unsigned int irqBit; ++ static unsigned int isrNumber = 31; ++ ++ pendingIrqs = PERF->IrqStatus & PERF->IrqMask; ++ if (!pendingIrqs) { ++ return; ++ } ++ ++ while (1) { ++ irqBit <<= 1; ++ isrNumber++; ++ if (isrNumber == 32) { ++ isrNumber = 0; ++ irqBit = 0x1; ++ } ++ if (pendingIrqs & irqBit) { ++ PERF->IrqMask &= ~irqBit; // mask ++ do_IRQ(isrNumber + INTERNAL_ISR_TABLE_OFFSET, regs); ++ break; ++ } ++ } ++} ++ ++static void irq_dispatch_ext(uint32 irq, struct pt_regs *regs) ++{ ++ if (!(PERF->ExtIrqCfg & (1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_MASK_SHFT)))) { ++ printk("**** Ext IRQ mask. Should not dispatch ****\n"); ++ } ++ /* disable and clear interrupt in the controller */ ++ PERF->ExtIrqCfg |= (1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_CLEAR_SHFT)); ++ PERF->ExtIrqCfg &= ~(1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_MASK_SHFT)); ++ do_IRQ(irq, regs); ++} ++ ++void brcm_irq_dispatch(struct pt_regs *regs) ++{ ++ u32 cause; ++ while((cause = (read_c0_cause()& CAUSEF_IP))) { ++ if (cause & CAUSEF_IP7) ++ do_IRQ(MIPS_TIMER_INT, regs); ++ else if (cause & CAUSEF_IP2) ++ irq_dispatch_int(regs); ++ else if (cause & CAUSEF_IP3) ++ irq_dispatch_ext(INTERRUPT_ID_EXTERNAL_0, regs); ++ else if (cause & CAUSEF_IP4) ++ irq_dispatch_ext(INTERRUPT_ID_EXTERNAL_1, regs); ++ else if (cause & CAUSEF_IP5) ++ irq_dispatch_ext(INTERRUPT_ID_EXTERNAL_2, regs); ++ else if (cause & CAUSEF_IP6) ++ irq_dispatch_ext(INTERRUPT_ID_EXTERNAL_3, regs); ++ //cli(); ++ spin_lock_irq(&irq_lock); ++ } ++} ++ ++void plat_irq_dispatch(struct pt_regs *regs) ++{ ++ u32 cause; ++ while((cause = (read_c0_cause()& CAUSEF_IP))) { ++ if (cause & CAUSEF_IP7) ++ do_IRQ(MIPS_TIMER_INT, regs); ++ else if (cause & CAUSEF_IP2) ++ irq_dispatch_int(regs); ++ else if (cause & CAUSEF_IP3) ++ irq_dispatch_ext(INTERRUPT_ID_EXTERNAL_0, regs); ++ else if (cause & CAUSEF_IP4) ++ irq_dispatch_ext(INTERRUPT_ID_EXTERNAL_1, regs); ++ else if (cause & CAUSEF_IP5) ++ irq_dispatch_ext(INTERRUPT_ID_EXTERNAL_2, regs); ++ else if (cause & CAUSEF_IP6) ++ irq_dispatch_ext(INTERRUPT_ID_EXTERNAL_3, regs); ++ //cli(); ++ spin_lock_irq(&irq_lock); ++ } ++} ++ ++ ++void enable_brcm_irq(unsigned int irq) ++{ ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ if( irq >= INTERNAL_ISR_TABLE_OFFSET ) { ++ PERF->IrqMask |= (1 << (irq - INTERNAL_ISR_TABLE_OFFSET)); ++ } ++ else if (irq >= INTERRUPT_ID_EXTERNAL_0 && irq <= INTERRUPT_ID_EXTERNAL_3) { ++ /* enable and clear interrupt in the controller */ ++ PERF->ExtIrqCfg |= (1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_CLEAR_SHFT)); ++ PERF->ExtIrqCfg |= (1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_MASK_SHFT)); ++ } ++ local_irq_restore(flags); ++} ++ ++void disable_brcm_irq(unsigned int irq) ++{ ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ if( irq >= INTERNAL_ISR_TABLE_OFFSET ) { ++ PERF->IrqMask &= ~(1 << (irq - INTERNAL_ISR_TABLE_OFFSET)); ++ } ++ else if (irq >= INTERRUPT_ID_EXTERNAL_0 && irq <= INTERRUPT_ID_EXTERNAL_3) { ++ /* disable interrupt in the controller */ ++ PERF->ExtIrqCfg &= ~(1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_MASK_SHFT)); ++ } ++ local_irq_restore(flags); ++} ++ ++void ack_brcm_irq(unsigned int irq) ++{ ++ /* Already done in brcm_irq_dispatch */ ++} ++ ++unsigned int startup_brcm_irq(unsigned int irq) ++{ ++ enable_brcm_irq(irq); ++ ++ return 0; /* never anything pending */ ++} ++ ++unsigned int startup_brcm_none(unsigned int irq) ++{ ++ return 0; ++} ++ ++void end_brcm_irq(unsigned int irq) ++{ ++ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) ++ enable_brcm_irq(irq); ++} ++ ++void end_brcm_none(unsigned int irq) ++{ ++} ++ ++#define ALLINTS_NOTIMER (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4) ++ ++static void __init brcm_irq_setup(void) ++{ ++ extern asmlinkage void brcmIRQ(void); ++ ++ clear_c0_status(ST0_BEV); ++ set_except_vector(0, brcmIRQ); ++ change_c0_status(ST0_IM, ALLINTS_NOTIMER); ++ ++#ifdef CONFIG_REMOTE_DEBUG ++ rs_kgdb_hook(0); ++#endif ++} ++ ++static struct hw_interrupt_type brcm_irq_type = { ++ .typename = "MIPS", ++ .startup = startup_brcm_irq, ++ .shutdown = disable_brcm_irq, ++ .enable = enable_brcm_irq, ++ .disable = disable_brcm_irq, ++ .ack = ack_brcm_irq, ++ .end = end_brcm_irq, ++ .set_affinity = NULL ++}; ++ ++static struct hw_interrupt_type brcm_irq_no_end_type = { ++ .typename = "MIPS", ++ .startup = startup_brcm_none, ++ .shutdown = disable_brcm_irq, ++ .enable = enable_brcm_irq, ++ .disable = disable_brcm_irq, ++ .ack = ack_brcm_irq, ++ .end = end_brcm_none, ++ .set_affinity = NULL ++}; ++ ++void __init arch_init_irq(void) ++{ ++ int i; ++ ++ for (i = 0; i < NR_IRQS; i++) { ++ irq_desc[i].status = IRQ_DISABLED; ++ irq_desc[i].action = 0; ++ irq_desc[i].depth = 1; ++ irq_desc[i].handler = &brcm_irq_type; ++ } ++ ++ brcm_irq_setup(); ++} ++ ++int request_external_irq(unsigned int irq, ++ FN_HANDLER handler, ++ unsigned long irqflags, ++ const char * devname, ++ void *dev_id) ++{ ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ ++ PERF->ExtIrqCfg |= (1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_CLEAR_SHFT)); // Clear ++ PERF->ExtIrqCfg &= ~(1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_MASK_SHFT)); // Mask ++ PERF->ExtIrqCfg &= ~(1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_INSENS_SHFT)); // Edge insesnsitive ++ PERF->ExtIrqCfg |= (1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_LEVEL_SHFT)); // Level triggered ++ PERF->ExtIrqCfg &= ~(1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_SENSE_SHFT)); // Low level ++ ++ local_irq_restore(flags); ++ ++ return( request_irq(irq, handler, irqflags, devname, dev_id) ); ++} ++ ++/* VxWorks compatibility function(s). */ ++ ++unsigned int BcmHalMapInterrupt(FN_HANDLER pfunc, unsigned int param, ++ unsigned int interruptId) ++{ ++ int nRet = -1; ++ char *devname; ++ ++ devname = kmalloc(16, GFP_KERNEL); ++ if (devname) ++ sprintf( devname, "brcm_%d", interruptId ); ++ ++ /* Set the IRQ description to not automatically enable the interrupt at ++ * the end of an ISR. The driver that handles the interrupt must ++ * explicitly call BcmHalInterruptEnable or enable_brcm_irq. This behavior ++ * is consistent with interrupt handling on VxWorks. ++ */ ++ irq_desc[interruptId].handler = &brcm_irq_no_end_type; ++ ++ if( interruptId >= INTERNAL_ISR_TABLE_OFFSET ) ++ { ++ nRet = request_irq( interruptId, pfunc, SA_SAMPLE_RANDOM | SA_INTERRUPT, ++ devname, (void *) param ); ++ } ++ else if (interruptId >= INTERRUPT_ID_EXTERNAL_0 && interruptId <= INTERRUPT_ID_EXTERNAL_3) ++ { ++ nRet = request_external_irq( interruptId, pfunc, SA_SAMPLE_RANDOM | SA_INTERRUPT, ++ devname, (void *) param ); ++ } ++ ++ return( nRet ); ++} ++ ++ ++/* Debug function. */ ++ ++void dump_intr_regs(void) ++{ ++ printk("PERF->ExtIrqCfg [%08x]\n", *(&(PERF->ExtIrqCfg))); ++} ++ ++EXPORT_SYMBOL(enable_brcm_irq); ++EXPORT_SYMBOL(disable_brcm_irq); ++EXPORT_SYMBOL(request_external_irq); ++EXPORT_SYMBOL(BcmHalMapInterrupt); ++ +diff -urN linux-2.6.17/arch/mips/brcm-boards/bcm963xx/Kconfig linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/Kconfig +--- linux-2.6.17/arch/mips/brcm-boards/bcm963xx/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/Kconfig 2006-08-03 16:36:58.000000000 +0200 +@@ -0,0 +1,172 @@ ++# Kernel and Driver configuration for Broadcom Commengine ADSL board ++choice ++ prompt "Broadcom Commengine ADSL board" ++ depends on MIPS_BRCM ++ default BCM96345 ++ help ++ Select different Broadcom ADSL board ++ ++config BCM96338 ++ bool "96338 ADSL board" ++ select DMA_NONCOHERENT ++ select HW_HAS_PCI ++ ++config BCM96345 ++ bool "96345 ADSL board" ++ select DMA_NONCOHERENT ++ select HW_HAS_PCI ++ ++config BCM96348 ++ bool "96348 ADSL board" ++ select DMA_NONCOHERENT ++ select HW_HAS_PCI ++ ++endchoice ++ ++config BCM_BOARD ++ bool "Support for Broadcom Board" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_SERIAL ++ bool "Support for Serial Port" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_ENET ++ tristate "Support for Ethernet" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_USB ++ tristate "Support for USB" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_WLAN ++ tristate "Support for Wireless" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_PCI ++ bool "Support for PCI" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ select PCI ++ ++config BCM_ATMAPI ++ tristate "Support for ATM" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_ATMTEST ++ tristate "Support for ATM Diagnostic" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_ADSL ++ tristate "Support for ADSL" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_ENDPOINT ++ tristate "Support for VOICE" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_PROCFS ++ tristate "Support for PROCFS" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_VDSL ++ tristate "Support for VDSL" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_SECURITY ++ tristate "Support for SECURITY" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_HPNA ++ tristate "Support for HPNA" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_BOARD_IMPL ++ int "Implementation index for ADSL Board" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_SERIAL_IMPL ++ int "Implementation index for Serial" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_ENET_IMPL ++ int "Implementation index for Ethernet" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_USB_IMPL ++ int "Implementation index for USB" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_WLAN_IMPL ++ int "Implementation index for WIRELESS" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_ATMAPI_IMPL ++ int "Implementation index for ATM" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_ATMTEST_IMPL ++ int "Implementation index for ATM Diagnostic" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_BLAA_IMPL ++ int "Implementation index for BLAA" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_ADSL_IMPL ++ int "Implementation index for ADSL" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_ENDPOINT_IMPL ++ int "Implementation index for VOICE" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_PROCFS_IMPL ++ int "Implementation index for PROCFS" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_VDSL_IMPL ++ int "Implementation index for VDSL" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_SECURITY_IMPL ++ int "Implementation index for SECURITY" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++config BCM_HPNA_IMPL ++ int "Implementation index for HPNA" ++ depends on BCM96338 || BCM96345 || BCM96348 ++ ++choice ++ prompt "Root File System" ++ depends on MIPS_BRCM ++ default ROOTFS_SQUASHFS ++ help ++ Select root file system on the board flash. ++ ++config ROOTFS_SQUASHFS ++ bool "SQUASHFS" ++config ROOTFS_CRAMFS ++ bool "CRAMFS" ++config ROOTFS_JFFS2 ++ bool "JFFS2" ++config ROOTFS_NFS ++ bool "NFS" ++ ++endchoice ++ ++config ROOT_FLASHFS ++ string "flash partition" ++ depends on ROOTFS_SQUASHFS || ROOTFS_CRAMFS || ROOTFS_JFFS2 ++ default "root=31:0 ro noinitrd" if ROOTFS_SQUASHFS = y || ROOTFS_CRAMFS = y ++ default "root=31:2 ro noinitrd" if ROOTFS_JFFS2 = y ++ help ++ This is the root file system partition on flash memory ++ ++config ROOT_NFS_DIR ++ string "NFS server path" ++ depends on ROOTFS_NFS ++ default "/opt/bcm96338/targets/96338R/fs" if BCM96338 = y ++ default "/opt/bcm96345/targets/96345R/fs" if BCM96345 = y ++ default "/opt/bcm96348/targets/96348R/fs" if BCM96348 = y ++ help ++ This is the path of NFS server (host system) +diff -urN linux-2.6.17/arch/mips/brcm-boards/bcm963xx/Makefile linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/Makefile +--- linux-2.6.17/arch/mips/brcm-boards/bcm963xx/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/Makefile 2006-08-03 16:36:58.000000000 +0200 +@@ -0,0 +1,23 @@ ++# ++# Makefile for generic Broadcom MIPS boards ++# ++# Copyright (C) 2004 Broadcom Corporation ++# ++obj-y := irq.o prom.o setup.o time.o ser_init.o bcm63xx_flash.o bcm63xx_led.o board.o boardparms.o cfiflash.o ++ ++SRCBASE := $(TOPDIR) ++EXTRA_CFLAGS += -I$(SRCBASE)/include ++#EXTRA_CFLAGS += -I$(INC_ADSLDRV_PATH) -DDBG ++EXTRA_CFLAGS += -I$(INC_ADSLDRV_PATH) ++ ++ ++ifeq "$(ADSL)" "ANNEX_B" ++EXTRA_CFLAGS += -DADSL_ANNEXB ++endif ++ifeq "$(ADSL)" "SADSL" ++EXTRA_CFLAGS += -DADSL_SADSL ++endif ++ifeq "$(ADSL)" "ANNEX_C" ++EXTRA_CFLAGS += -DADSL_ANNEXC ++endif ++ +diff -urN linux-2.6.17/arch/mips/brcm-boards/bcm963xx/prom.c linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/prom.c +--- linux-2.6.17/arch/mips/brcm-boards/bcm963xx/prom.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/prom.c 2006-08-03 16:40:27.000000000 +0200 +@@ -0,0 +1,250 @@ ++/* ++<:copyright-gpl ++ Copyright 2004 Broadcom Corp. All Rights Reserved. ++ ++ This program is free software; you can distribute it and/or modify it ++ under the terms of the GNU General Public License (Version 2) as ++ published by the Free Software Foundation. ++ ++ This program is distributed in the hope it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++:> ++*/ ++/* ++ * prom.c: PROM library initialization code. ++ * ++ */ ++#include <linux/init.h> ++#include <linux/mm.h> ++#include <linux/sched.h> ++#include <linux/bootmem.h> ++#include <linux/blkdev.h> ++#include <asm/addrspace.h> ++#include <asm/bootinfo.h> ++#include <asm/cpu.h> ++#include <asm/time.h> ++ ++#include <bcm_map_part.h> ++#include <board.h> ++#include "boardparms.h" ++#include "softdsl/AdslCoreDefs.h" ++ ++ ++//char arcs_cmdline[CL_SIZE] __initdata = {0}; ++/* inv_xde */ ++int boot_loader_type; ++ ++extern int do_syslog(int, char *, int); ++extern void serial_init(void); ++extern void __init InitNvramInfo( void ); ++extern void kerSysFlashInit( void ); ++extern unsigned long get_nvram_start_addr(void); ++void __init create_root_nfs_cmdline( char *cmdline ); ++ ++#if defined(CONFIG_BCM96338) ++#define CPU_CLOCK 240000000 ++#define MACH_BCM MACH_BCM96338 ++#endif ++#if defined(CONFIG_BCM96345) ++#define CPU_CLOCK 140000000 ++#define MACH_BCM MACH_BCM96345 ++#endif ++#if defined(CONFIG_BCM96348) ++void __init calculateCpuSpeed(void); ++static unsigned long cpu_speed; ++#define CPU_CLOCK cpu_speed ++#define MACH_BCM MACH_BCM96348 ++#endif ++ ++const char *get_system_type(void) ++{ ++ /*PNVRAM_DATA pNvramData = (PNVRAM_DATA) get_nvram_start_addr(); ++ ++ return( pNvramData->szBoardId );*/ ++ return "brcm63xx"; ++} ++ ++unsigned long getMemorySize(void) ++{ ++ unsigned long ulSdramType = BOARD_SDRAM_TYPE; ++ ++ unsigned long ulSdramSize; ++ ++ switch( ulSdramType ) ++ { ++ case BP_MEMORY_16MB_1_CHIP: ++ case BP_MEMORY_16MB_2_CHIP: ++ ulSdramSize = 16 * 1024 * 1024; ++ break; ++ case BP_MEMORY_32MB_1_CHIP: ++ case BP_MEMORY_32MB_2_CHIP: ++ ulSdramSize = 32 * 1024 * 1024; ++ break; ++ case BP_MEMORY_64MB_2_CHIP: ++ ulSdramSize = 64 * 1024 * 1024; ++ break; ++ default: ++ ulSdramSize = 8 * 1024 * 1024; ++ break; ++ } + if (boot_loader_type == BOOT_CFE) ++ return ulSdramSize; ++ else ++ // assume that there is one contiguous memory map ++ return boot_mem_map.map[0].size; ++} ++ ++/* -------------------------------------------------------------------------- ++ Name: prom_init ++ -------------------------------------------------------------------------- */ ++void __init prom_init(void) ++{ ++ extern ulong r4k_interval; ++ ++ serial_init(); ++ ++ /* Need to fixup boot loader detection code ++ * whithout changing prom_init prototype ++ */ ++ + if (boot_loader_type == BOOT_CFE) ++ kerSysFlashInit(); ++ ++ do_syslog(8, NULL, 8); ++ ++ printk( "%s prom init\n", get_system_type() ); ++ ++ PERF->IrqMask = 0; ++ ++ arcs_cmdline[0] = '\0'; ++#if defined(CONFIG_ROOT_NFS) ++ create_root_nfs_cmdline( arcs_cmdline ); ++#elif defined(CONFIG_ROOT_FLASHFS) ++ strcpy(arcs_cmdline, CONFIG_ROOT_FLASHFS); ++#endif ++//#define ADSL_SDRAM_IMAGE_SIZE 0x40000 ++ /* inv_xde */ ++ //add_memory_region(0, (getMemorySize() - ADSL_SDRAM_IMAGE_SIZE), BOOT_MEM_RAM); + if (boot_loader_type == BOOT_CFE) ++ add_memory_region(0, (getMemorySize() - ADSL_SDRAM_IMAGE_SIZE), BOOT_MEM_RAM); ++ else ++ add_memory_region(0, (0x01000000 - ADSL_SDRAM_IMAGE_SIZE), BOOT_MEM_RAM); ++#if defined(CONFIG_BCM96348) ++ calculateCpuSpeed(); ++#endif ++ /* Count register increments every other clock */ ++ r4k_interval = CPU_CLOCK / HZ / 2; ++ mips_hpt_frequency = CPU_CLOCK / 2; ++ ++ mips_machgroup = MACH_GROUP_BRCM; ++ mips_machtype = MACH_BCM; ++} ++ ++/* -------------------------------------------------------------------------- ++ Name: prom_free_prom_memory ++Abstract: ++ -------------------------------------------------------------------------- */ ++void __init prom_free_prom_memory(void) ++{ ++ ++} ++ ++#if 0 ++#if defined(CONFIG_ROOT_NFS) ++/* This function reads in a line that looks something like this: ++ * ++ * + * CFE bootline=bcmEnet(0,0)host:vmlinux e=192.169.0.100:ffffff00 h=192.169.0.1 ++ * ++ * ++ * and retuns in the cmdline parameter some that looks like this: ++ * ++ * CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.1:/opt/targets/96345R/fs ++ * ip=192.168.0.100:192.168.0.1::255.255.255.0::eth0:off rw" ++ */ ++#define BOOT_LINE_ADDR 0x0 ++#define HEXDIGIT(d) ((d >= '0' && d <= '9') ? (d - '0') : ((d | 0x20) - 'W')) ++#define HEXBYTE(b) (HEXDIGIT((b)[0]) << 4) + HEXDIGIT((b)[1]) ++extern unsigned long get_nvram_start_addr(void); ++ ++void __init create_root_nfs_cmdline( char *cmdline ) ++{ ++ char root_nfs_cl[] = "root=/dev/nfs nfsroot=%s:" CONFIG_ROOT_NFS_DIR ++ " ip=%s:%s::%s::eth0:off rw"; ++ ++ char *localip = NULL; ++ char *hostip = NULL; ++ char mask[16] = ""; ++ PNVRAM_DATA pNvramData = (PNVRAM_DATA) get_nvram_start_addr(); ++ char bootline[128] = ""; ++ char *p = bootline; ++ ++ memcpy(bootline, pNvramData->szBootline, sizeof(bootline)); ++ while( *p ) ++ { ++ if( p[0] == 'e' && p[1] == '=' ) ++ { ++ /* Found local ip address */ ++ p += 2; ++ localip = p; ++ while( *p && *p != ' ' && *p != ':' ) ++ p++; ++ if( *p == ':' ) ++ { ++ /* Found network mask (eg FFFFFF00 */ ++ *p++ = '\0'; ++ sprintf( mask, "%u.%u.%u.%u", HEXBYTE(p), HEXBYTE(p + 2), ++ HEXBYTE(p + 4), HEXBYTE(p + 6) ); ++ p += 4; ++ } ++ else if( *p == ' ' ) ++ *p++ = '\0'; ++ } ++ else if( p[0] == 'h' && p[1] == '=' ) ++ { ++ /* Found host ip address */ ++ p += 2; ++ hostip = p; ++ while( *p && *p != ' ' ) ++ p++; ++ if( *p == ' ' ) ++ *p++ = '\0'; ++ } ++ else ++ p++; ++ } ++ ++ if( localip && hostip ) ++ sprintf( cmdline, root_nfs_cl, hostip, localip, hostip, mask ); ++} ++#endif ++#endif ++ ++#if defined(CONFIG_BCM96348) ++/* ********************************************************************* ++ * calculateCpuSpeed() ++ * Calculate the BCM6348 CPU speed by reading the PLL strap register ++ * and applying the following formula: ++ * cpu_clk = (.25 * 64MHz freq) * (N1 + 1) * (N2 + 2) / (M1_CPU + 1) ++ * Input parameters: ++ * none ++ * Return value: ++ * none ++ ********************************************************************* */ ++void __init calculateCpuSpeed(void) ++{ ++ UINT32 pllStrap = PERF->PllStrap; ++ int n1 = (pllStrap & PLL_N1_MASK) >> PLL_N1_SHFT; ++ int n2 = (pllStrap & PLL_N2_MASK) >> PLL_N2_SHFT; ++ int m1cpu = (pllStrap & PLL_M1_CPU_MASK) >> PLL_M1_CPU_SHFT; ++ ++ cpu_speed = (16 * (n1 + 1) * (n2 + 2) / (m1cpu + 1)) * 1000000; ++} ++#endif ++ +diff -urN linux-2.6.17/arch/mips/brcm-boards/bcm963xx/ser_init.c linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/ser_init.c +--- linux-2.6.17/arch/mips/brcm-boards/bcm963xx/ser_init.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/ser_init.c 2006-08-03 16:36:58.000000000 +0200 +@@ -0,0 +1,180 @@ ++/* ++<:copyright-gpl ++ Copyright 2004 Broadcom Corp. All Rights Reserved. ++ ++ This program is free software; you can distribute it and/or modify it ++ under the terms of the GNU General Public License (Version 2) as ++ published by the Free Software Foundation. ++ ++ This program is distributed in the hope it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++:> ++*/ ++/* ++ * Broadcom bcm63xx serial port initialization, also prepare for printk ++ * by registering with console_init ++ * ++ */ ++ ++#include <linux/config.h> ++#include <linux/init.h> ++#include <linux/interrupt.h> ++#include <linux/kernel.h> ++#include <linux/types.h> ++#include <linux/console.h> ++#include <linux/sched.h> ++ ++#include <asm/addrspace.h> ++#include <asm/irq.h> ++#include <asm/reboot.h> ++#include <asm/gdb-stub.h> ++#include <asm/mc146818rtc.h> ++ ++#include <bcm_map_part.h> ++#include <board.h> ++ ++#define SER63XX_DEFAULT_BAUD 115200 ++#define BD_BCM63XX_TIMER_CLOCK_INPUT (FPERIPH) ++#define stUart ((volatile Uart * const) UART_BASE) ++ ++// Transmit interrupts ++#define TXINT (TXFIFOEMT | TXUNDERR | TXOVFERR) ++// Receive interrupts ++#define RXINT (RXFIFONE | RXOVFERR) ++ ++/* -------------------------------------------------------------------------- ++ Name: serial_init ++ Purpose: Initalize the UART ++-------------------------------------------------------------------------- */ ++void __init serial_init(void) ++{ ++ UINT32 tmpVal = SER63XX_DEFAULT_BAUD; ++ ULONG clockFreqHz; ++ ++#if defined(CONFIG_BCM96345) ++ // Make sure clock is ticking ++ PERF->blkEnables |= UART_CLK_EN; ++#endif ++ ++ /* Dissable channel's receiver and transmitter. */ ++ stUart->control &= ~(BRGEN|TXEN|RXEN); ++ ++ /*--------------------------------------------------------------------*/ ++ /* Write the table value to the clock select register. */ ++ /* DPullen - this is the equation to use: */ ++ /* value = clockFreqHz / baud / 32-1; */ ++ /* (snmod) Actually you should also take into account any necessary */ ++ /* rounding. Divide by 16, look at lsb, if 0, divide by 2 */ ++ /* and subtract 1. If 1, just divide by 2 */ ++ /*--------------------------------------------------------------------*/ ++ clockFreqHz = BD_BCM63XX_TIMER_CLOCK_INPUT; ++ tmpVal = (clockFreqHz / tmpVal) / 16; ++ if( tmpVal & 0x01 ) ++ tmpVal /= 2; //Rounding up, so sub is already accounted for ++ else ++ tmpVal = (tmpVal / 2) - 1; // Rounding down so we must sub 1 ++ stUart->baudword = tmpVal; ++ ++ /* Finally, re-enable the transmitter and receiver. */ ++ stUart->control |= (BRGEN|TXEN|RXEN); ++ ++ stUart->config = (BITS8SYM | ONESTOP); ++ // Set the FIFO interrupt depth ... stUart->fifocfg = 0xAA; ++ stUart->fifoctl = RSTTXFIFOS | RSTRXFIFOS; ++ stUart->intMask = 0; ++ stUart->intMask = RXINT | TXINT; ++} ++ ++ ++/* prom_putc() ++ * Output a character to the UART ++ */ ++void prom_putc(char c) ++{ ++ /* Wait for Tx uffer to empty */ ++ while (! (READ16(stUart->intStatus) & TXFIFOEMT)); ++ /* Send character */ ++ stUart->Data = c; ++} ++ ++/* prom_puts() ++ * Write a string to the UART ++ */ ++void prom_puts(const char *s) ++{ ++ while (*s) { ++ if (*s == '\n') { ++ prom_putc('\r'); ++ } ++ prom_putc(*s++); ++ } ++} ++ ++ ++/* prom_getc_nowait() ++ * Returns a character from the UART ++ * Returns -1 if no characters available or corrupted ++ */ ++int prom_getc_nowait(void) ++{ ++ uint16 uStatus; ++ int cData = -1; ++ ++ uStatus = READ16(stUart->intStatus); ++ ++ if (uStatus & RXFIFONE) { /* Do we have a character? */ ++ cData = READ16(stUart->Data) & 0xff; /* Read character */ ++ if (uStatus & (RXFRAMERR | RXPARERR)) { /* If we got an error, throw it away */ ++ cData = -1; ++ } ++ } ++ ++ return cData; ++} ++ ++/* prom_getc() ++ * Returns a charcter from the serial port ++ * Will block until it receives a valid character ++*/ ++char prom_getc(void) ++{ ++ int cData = -1; ++ ++ /* Loop until we get a valid character */ ++ while(cData == -1) { ++ cData = prom_getc_nowait(); ++ } ++ return (char) cData; ++} ++ ++/* prom_testc() ++ * Returns 0 if no characters available ++ */ ++int prom_testc(void) ++{ ++ uint16 uStatus; ++ ++ uStatus = READ16(stUart->intStatus); ++ ++ return (uStatus & RXFIFONE); ++} ++ ++#if defined (CONFIG_REMOTE_DEBUG) ++/* Prevent other code from writing to the serial port */ ++void _putc(char c) { } ++void _puts(const char *ptr) { } ++#else ++/* Low level outputs call prom routines */ ++void _putc(char c) { ++ prom_putc(c); ++} ++void _puts(const char *ptr) { ++ prom_puts(ptr); ++} ++#endif +diff -urN linux-2.6.17/arch/mips/brcm-boards/bcm963xx/setup.c linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/setup.c +--- linux-2.6.17/arch/mips/brcm-boards/bcm963xx/setup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/setup.c 2006-08-03 16:36:58.000000000 +0200 +@@ -0,0 +1,523 @@ ++/* ++<:copyright-gpl ++ Copyright 2002 Broadcom Corp. All Rights Reserved. ++ ++ This program is free software; you can distribute it and/or modify it ++ under the terms of the GNU General Public License (Version 2) as ++ published by the Free Software Foundation. ++ ++ This program is distributed in the hope it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++:> ++*/ ++/* ++ * Generic setup routines for Broadcom 963xx MIPS boards ++ */ ++ ++#include <linux/config.h> ++#include <linux/init.h> ++#include <linux/interrupt.h> ++#include <linux/kernel.h> ++#include <linux/kdev_t.h> ++#include <linux/types.h> ++#include <linux/console.h> ++#include <linux/sched.h> ++#include <linux/mm.h> ++#include <linux/slab.h> ++#include <linux/module.h> ++#include <linux/pm.h> ++ ++#include <asm/addrspace.h> ++#include <asm/bcache.h> ++#include <asm/irq.h> ++#include <asm/time.h> ++#include <asm/reboot.h> ++#include <asm/gdb-stub.h> ++ ++extern void brcm_timer_setup(struct irqaction *irq); ++extern unsigned long getMemorySize(void); ++ ++#if defined(CONFIG_BCM96348) && defined(CONFIG_PCI) ++#include <linux/pci.h> ++#include <linux/delay.h> ++#include <bcm_map_part.h> ++#include <bcmpci.h> ++ ++static volatile MpiRegisters * mpi = (MpiRegisters *)(MPI_BASE); ++#endif ++ ++/* This function should be in a board specific directory. For now, ++ * assume that all boards that include this file use a Broadcom chip ++ * with a soft reset bit in the PLL control register. ++ */ ++static void brcm_machine_restart(char *command) ++{ ++ const unsigned long ulSoftReset = 0x00000001; ++ unsigned long *pulPllCtrl = (unsigned long *) 0xfffe0008; ++ *pulPllCtrl |= ulSoftReset; ++} ++ ++static void brcm_machine_halt(void) ++{ ++ printk("System halted\n"); ++ while (1); ++} ++ ++#if defined(CONFIG_BCM96348) && defined(CONFIG_PCI) ++ ++static void mpi_SetLocalPciConfigReg(uint32 reg, uint32 value) ++{ ++ /* write index then value */ ++ mpi->pcicfgcntrl = PCI_CFG_REG_WRITE_EN + reg;; ++ mpi->pcicfgdata = value; ++} ++ ++static uint32 mpi_GetLocalPciConfigReg(uint32 reg) ++{ ++ /* write index then get value */ ++ mpi->pcicfgcntrl = PCI_CFG_REG_WRITE_EN + reg;; ++ return mpi->pcicfgdata; ++} ++ ++/* ++ * mpi_ResetPcCard: Set/Reset the PcCard ++ */ ++static void mpi_ResetPcCard(int cardtype, BOOL bReset) ++{ ++ if (cardtype == MPI_CARDTYPE_NONE) { ++ return; ++ } ++ ++ if (cardtype == MPI_CARDTYPE_CARDBUS) { ++ bReset = ! bReset; ++ } ++ ++ if (bReset) { ++ mpi->pcmcia_cntl1 = (mpi->pcmcia_cntl1 & ~PCCARD_CARD_RESET); ++ } else { ++ mpi->pcmcia_cntl1 = (mpi->pcmcia_cntl1 | PCCARD_CARD_RESET); ++ } ++} ++ ++/* ++ * mpi_ConfigCs: Configure an MPI/EBI chip select ++ */ ++static void mpi_ConfigCs(uint32 cs, uint32 base, uint32 size, uint32 flags) ++{ ++ mpi->cs[cs].base = ((base & 0x1FFFFFFF) | size); ++ mpi->cs[cs].config = flags; ++} ++ ++/* ++ * mpi_InitPcmciaSpace ++ */ ++static void mpi_InitPcmciaSpace(void) ++{ ++ // ChipSelect 4 controls PCMCIA Memory accesses ++ mpi_ConfigCs(PCMCIA_COMMON_BASE, pcmciaMem, EBI_SIZE_1M, (EBI_WORD_WIDE|EBI_ENABLE)); ++ // ChipSelect 5 controls PCMCIA Attribute accesses ++ mpi_ConfigCs(PCMCIA_ATTRIBUTE_BASE, pcmciaAttr, EBI_SIZE_1M, (EBI_WORD_WIDE|EBI_ENABLE)); ++ // ChipSelect 6 controls PCMCIA I/O accesses ++ mpi_ConfigCs(PCMCIA_IO_BASE, pcmciaIo, EBI_SIZE_64K, (EBI_WORD_WIDE|EBI_ENABLE)); ++ ++ mpi->pcmcia_cntl2 = ((PCMCIA_ATTR_ACTIVE << RW_ACTIVE_CNT_BIT) | ++ (PCMCIA_ATTR_INACTIVE << INACTIVE_CNT_BIT) | ++ (PCMCIA_ATTR_CE_SETUP << CE_SETUP_CNT_BIT) | ++ (PCMCIA_ATTR_CE_HOLD << CE_HOLD_CNT_BIT)); ++ ++ mpi->pcmcia_cntl2 |= (PCMCIA_HALFWORD_EN | PCMCIA_BYTESWAP_DIS); ++} ++ ++/* ++ * cardtype_vcc_detect: PC Card's card detect and voltage sense connection ++ * ++ * CD1#/ CD2#/ VS1#/ VS2#/ Card Initial Vcc ++ * CCD1# CCD2# CVS1 CVS2 Type ++ * ++ * GND GND open open 16-bit 5 vdc ++ * ++ * GND GND GND open 16-bit 3.3 vdc ++ * ++ * GND GND open GND 16-bit x.x vdc ++ * ++ * GND GND GND GND 16-bit 3.3 & x.x vdc ++ * ++ *==================================================================== ++ * ++ * CVS1 GND CCD1# open CardBus 3.3 vdc ++ * ++ * GND CVS2 open CCD2# CardBus x.x vdc ++ * ++ * GND CVS1 CCD2# open CardBus y.y vdc ++ * ++ * GND CVS2 GND CCD2# CardBus 3.3 & x.x vdc ++ * ++ * CVS2 GND open CCD1# CardBus x.x & y.y vdc ++ * ++ * GND CVS1 CCD2# open CardBus 3.3, x.x & y.y vdc ++ * ++ */ ++static int cardtype_vcc_detect(void) ++{ ++ uint32 data32; ++ int cardtype; ++ ++ cardtype = MPI_CARDTYPE_NONE; ++ mpi->pcmcia_cntl1 = 0x0000A000; // Turn on the output enables and drive ++ // the CVS pins to 0. ++ data32 = mpi->pcmcia_cntl1; ++ switch (data32 & 0x00000003) // Test CD1# and CD2#, see if card is plugged in. ++ { ++ case 0x00000003: // No Card is in the slot. ++ printk("mpi: No Card is in the PCMCIA slot\n"); ++ break; ++ ++ case 0x00000002: // Partial insertion, No CD2#. ++ printk("mpi: Card in the PCMCIA slot partial insertion, no CD2 signal\n"); ++ break; ++ ++ case 0x00000001: // Partial insertion, No CD1#. ++ printk("mpi: Card in the PCMCIA slot partial insertion, no CD1 signal\n"); ++ break; ++ ++ case 0x00000000: ++ mpi->pcmcia_cntl1 = 0x0000A0C0; // Turn off the CVS output enables and ++ // float the CVS pins. ++ mdelay(1); ++ data32 = mpi->pcmcia_cntl1; ++ // Read the Register. ++ switch (data32 & 0x0000000C) // See what is on the CVS pins. ++ { ++ case 0x00000000: // CVS1 and CVS2 are tied to ground, only 1 option. ++ printk("mpi: Detected 3.3 & x.x 16-bit PCMCIA card\n"); ++ cardtype = MPI_CARDTYPE_PCMCIA; ++ break; ++ ++ case 0x00000004: // CVS1 is open or tied to CCD1/CCD2 and CVS2 is tied to ground. ++ // 2 valid voltage options. ++ switch (data32 & 0x00000003) // Test the values of CCD1 and CCD2. ++ { ++ case 0x00000003: // CCD1 and CCD2 are tied to 1 of the CVS pins. ++ // This is not a valid combination. ++ printk("mpi: Unknown card plugged into slot\n"); ++ break; ++ ++ case 0x00000002: // CCD2 is tied to either CVS1 or CVS2. ++ mpi->pcmcia_cntl1 = 0x0000A080; // Drive CVS1 to a 0. ++ mdelay(1); ++ data32 = mpi->pcmcia_cntl1; ++ if (data32 & 0x00000002) { // CCD2 is tied to CVS2, not valid. ++ printk("mpi: Unknown card plugged into slot\n"); ++ } else { // CCD2 is tied to CVS1. ++ printk("mpi: Detected 3.3, x.x and y.y Cardbus card\n"); ++ cardtype = MPI_CARDTYPE_CARDBUS; ++ } ++ break; ++ ++ case 0x00000001: // CCD1 is tied to either CVS1 or CVS2. ++ // This is not a valid combination. ++ printk("mpi: Unknown card plugged into slot\n"); ++ break; ++ ++ case 0x00000000: // CCD1 and CCD2 are tied to ground. ++ printk("mpi: Detected x.x vdc 16-bit PCMCIA card\n"); ++ cardtype = MPI_CARDTYPE_PCMCIA; ++ break; ++ } ++ break; ++ ++ case 0x00000008: // CVS2 is open or tied to CCD1/CCD2 and CVS1 is tied to ground. ++ // 2 valid voltage options. ++ switch (data32 & 0x00000003) // Test the values of CCD1 and CCD2. ++ { ++ case 0x00000003: // CCD1 and CCD2 are tied to 1 of the CVS pins. ++ // This is not a valid combination. ++ printk("mpi: Unknown card plugged into slot\n"); ++ break; ++ ++ case 0x00000002: // CCD2 is tied to either CVS1 or CVS2. ++ mpi->pcmcia_cntl1 = 0x0000A040; // Drive CVS2 to a 0. ++ mdelay(1); ++ data32 = mpi->pcmcia_cntl1; ++ if (data32 & 0x00000002) { // CCD2 is tied to CVS1, not valid. ++ printk("mpi: Unknown card plugged into slot\n"); ++ } else {// CCD2 is tied to CVS2. ++ printk("mpi: Detected 3.3 and x.x Cardbus card\n"); ++ cardtype = MPI_CARDTYPE_CARDBUS; ++ } ++ break; ++ ++ case 0x00000001: // CCD1 is tied to either CVS1 or CVS2. ++ // This is not a valid combination. ++ printk("mpi: Unknown card plugged into slot\n"); ++ break; ++ ++ case 0x00000000: // CCD1 and CCD2 are tied to ground. ++ cardtype = MPI_CARDTYPE_PCMCIA; ++ printk("mpi: Detected 3.3 vdc 16-bit PCMCIA card\n"); ++ break; ++ } ++ break; ++ ++ case 0x0000000C: // CVS1 and CVS2 are open or tied to CCD1/CCD2. ++ // 5 valid voltage options. ++ ++ switch (data32 & 0x00000003) // Test the values of CCD1 and CCD2. ++ { ++ case 0x00000003: // CCD1 and CCD2 are tied to 1 of the CVS pins. ++ // This is not a valid combination. ++ printk("mpi: Unknown card plugged into slot\n"); ++ break; ++ ++ case 0x00000002: // CCD2 is tied to either CVS1 or CVS2. ++ // CCD1 is tied to ground. ++ mpi->pcmcia_cntl1 = 0x0000A040; // Drive CVS2 to a 0. ++ mdelay(1); ++ data32 = mpi->pcmcia_cntl1; ++ if (data32 & 0x00000002) { // CCD2 is tied to CVS1. ++ printk("mpi: Detected y.y vdc Cardbus card\n"); ++ } else { // CCD2 is tied to CVS2. ++ printk("mpi: Detected x.x vdc Cardbus card\n"); ++ } ++ cardtype = MPI_CARDTYPE_CARDBUS; ++ break; ++ ++ case 0x00000001: // CCD1 is tied to either CVS1 or CVS2. ++ // CCD2 is tied to ground. ++ ++ mpi->pcmcia_cntl1 = 0x0000A040; // Drive CVS2 to a 0. ++ mdelay(1); ++ data32 = mpi->pcmcia_cntl1; ++ if (data32 & 0x00000001) {// CCD1 is tied to CVS1. ++ printk("mpi: Detected 3.3 vdc Cardbus card\n"); ++ } else { // CCD1 is tied to CVS2. ++ printk("mpi: Detected x.x and y.y Cardbus card\n"); ++ } ++ cardtype = MPI_CARDTYPE_CARDBUS; ++ break; ++ ++ case 0x00000000: // CCD1 and CCD2 are tied to ground. ++ cardtype = MPI_CARDTYPE_PCMCIA; ++ printk("mpi: Detected 5 vdc 16-bit PCMCIA card\n"); ++ break; ++ } ++ break; ++ ++ default: ++ printk("mpi: Unknown card plugged into slot\n"); ++ break; ++ ++ } ++ } ++ return cardtype; ++} ++ ++/* ++ * mpi_DetectPcCard: Detect the plugged in PC-Card ++ * Return: < 0 => Unknown card detected ++ * 0 => No card detected ++ * 1 => 16-bit card detected ++ * 2 => 32-bit CardBus card detected ++ */ ++static int mpi_DetectPcCard(void) ++{ ++ int cardtype; ++ ++ cardtype = cardtype_vcc_detect(); ++ switch(cardtype) { ++ case MPI_CARDTYPE_PCMCIA: ++ mpi->pcmcia_cntl1 &= ~0x0000e000; // disable enable bits ++ //mpi->pcmcia_cntl1 = (mpi->pcmcia_cntl1 & ~PCCARD_CARD_RESET); ++ mpi->pcmcia_cntl1 |= (PCMCIA_ENABLE | PCMCIA_GPIO_ENABLE); ++ mpi_InitPcmciaSpace(); ++ mpi_ResetPcCard(cardtype, FALSE); ++ // Hold card in reset for 10ms ++ mdelay(10); ++ mpi_ResetPcCard(cardtype, TRUE); ++ // Let card come out of reset ++ mdelay(100); ++ break; ++ case MPI_CARDTYPE_CARDBUS: ++ // 8 => CardBus Enable ++ // 1 => PCI Slot Number ++ // C => Float VS1 & VS2 ++ mpi->pcmcia_cntl1 = (mpi->pcmcia_cntl1 & 0xFFFF0000) | ++ CARDBUS_ENABLE | ++ (CARDBUS_SLOT << 8)| ++ VS2_OEN | ++ VS1_OEN; ++ /* access to this memory window will be to/from CardBus */ ++ mpi->l2pmremap1 |= CARDBUS_MEM; ++ ++ // Need to reset the Cardbus Card. There's no CardManager to do this, ++ // and we need to be ready for PCI configuration. ++ mpi_ResetPcCard(cardtype, FALSE); ++ // Hold card in reset for 10ms ++ mdelay(10); ++ mpi_ResetPcCard(cardtype, TRUE); ++ // Let card come out of reset ++ mdelay(100); ++ break; ++ default: ++ break; ++ } ++ return cardtype; ++} ++ ++static int mpi_init(void) ++{ ++ unsigned long data; ++ unsigned int chipid; ++ unsigned int chiprev; ++ unsigned int sdramsize; ++ ++ chipid = (PERF->RevID & 0xFFFF0000) >> 16; ++ chiprev = (PERF->RevID & 0xFF); ++ sdramsize = getMemorySize(); ++ /* ++ * Init the pci interface ++ */ ++ data = GPIO->GPIOMode; // GPIO mode register ++ data |= GROUP2_PCI | GROUP1_MII_PCCARD; // PCI internal arbiter + Cardbus ++ GPIO->GPIOMode = data; // PCI internal arbiter ++ ++ /* ++ * In the BCM6348 CardBus support is defaulted to Slot 0 ++ * because there is no external IDSEL for CardBus. To disable ++ * the CardBus and allow a standard PCI card in Slot 0 ++ * set the cbus_idsel field to 0x1f. ++ */ ++ /* ++ uData = mpi->pcmcia_cntl1; ++ uData |= CARDBUS_IDSEL; ++ mpi->pcmcia_cntl1 = uData; ++ */ ++ // Setup PCI I/O Window range. Give 64K to PCI I/O ++ mpi->l2piorange = ~(BCM_PCI_IO_SIZE_64KB-1); ++ // UBUS to PCI I/O base address ++ mpi->l2piobase = BCM_PCI_IO_BASE & BCM_PCI_ADDR_MASK; ++ // UBUS to PCI I/O Window remap ++ mpi->l2pioremap = (BCM_PCI_IO_BASE | MEM_WINDOW_EN); ++ ++ // enable PCI related GPIO pins and data swap between system and PCI bus ++ mpi->locbuscntrl = (EN_PCI_GPIO | DIR_U2P_NOSWAP); ++ ++ /* Enable 6348 BusMaster and Memory access mode */ ++ data = mpi_GetLocalPciConfigReg(PCI_COMMAND); ++ data |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); ++ mpi_SetLocalPciConfigReg(PCI_COMMAND, data); ++ ++ /* Configure two 16 MByte PCI to System memory regions. */ ++ /* These memory regions are used when PCI device is a bus master */ ++ /* Accesses to the SDRAM from PCI bus will be "byte swapped" for this region */ ++ mpi_SetLocalPciConfigReg(PCI_BASE_ADDRESS_3, BCM_HOST_MEM_SPACE1); ++ mpi->sp0remap = 0x0; ++ ++ /* Accesses to the SDRAM from PCI bus will not be "byte swapped" for this region */ ++ mpi_SetLocalPciConfigReg(PCI_BASE_ADDRESS_4, BCM_HOST_MEM_SPACE2); ++ mpi->sp1remap = 0x0; ++ mpi->pcimodesel |= (PCI_BAR2_NOSWAP | 0x40); ++ ++ if ((chipid == 0x6348) && (chiprev == 0xb0)) { ++ mpi->sp0range = ~(sdramsize-1); ++ mpi->sp1range = ~(sdramsize-1); ++ } ++ /* ++ * Change 6348 PCI Cfg Reg. offset 0x40 to PCI memory read retry count infinity ++ * by set 0 in bit 8~15. This resolve read Bcm4306 srom return 0xffff in ++ * first read. ++ */ ++ data = mpi_GetLocalPciConfigReg(BRCM_PCI_CONFIG_TIMER); ++ data &= ~BRCM_PCI_CONFIG_TIMER_RETRY_MASK; ++ data |= 0x00000080; ++ mpi_SetLocalPciConfigReg(BRCM_PCI_CONFIG_TIMER, data); ++ ++ /* enable pci interrupt */ ++ mpi->locintstat |= (EXT_PCI_INT << 16); ++ ++ mpi_DetectPcCard(); ++ ++ ioport_resource.start = BCM_PCI_IO_BASE; ++ ioport_resource.end = BCM_PCI_IO_BASE + BCM_PCI_IO_SIZE_64KB; ++ ++#if defined(CONFIG_USB) ++ PERF->blkEnables |= USBH_CLK_EN; ++ mdelay(100); ++ *USBH_NON_OHCI = NON_OHCI_BYTE_SWAP; ++#endif ++ ++ return 0; ++} ++#endif ++ ++static int __init brcm63xx_setup(void) ++{ ++ extern int panic_timeout; ++ ++ _machine_restart = brcm_machine_restart; ++ _machine_halt = brcm_machine_halt; ++ pm_power_off = brcm_machine_halt; ++ ++ board_timer_setup = brcm_timer_setup; ++ ++ panic_timeout = 5; ++ ++#if defined(CONFIG_BCM96348) && defined(CONFIG_PCI) ++ /* mpi initialization */ ++ mpi_init(); ++#endif ++ return 0; ++} ++ ++void plat_setup(void) ++{ ++ brcm63xx_setup(); ++} ++ ++/*************************************************************************** ++ * C++ New and delete operator functions ++ ***************************************************************************/ ++ ++/* void *operator new(unsigned int sz) */ ++void *_Znwj(unsigned int sz) ++{ ++ return( kmalloc(sz, GFP_KERNEL) ); ++} ++ ++/* void *operator new[](unsigned int sz)*/ ++void *_Znaj(unsigned int sz) ++{ ++ return( kmalloc(sz, GFP_KERNEL) ); ++} ++ ++/* placement new operator */ ++/* void *operator new (unsigned int size, void *ptr) */ ++void *ZnwjPv(unsigned int size, void *ptr) ++{ ++ return ptr; ++} ++ ++/* void operator delete(void *m) */ ++void _ZdlPv(void *m) ++{ ++ kfree(m); ++} ++ ++/* void operator delete[](void *m) */ ++void _ZdaPv(void *m) ++{ ++ kfree(m); ++} ++ ++EXPORT_SYMBOL(_Znwj); ++EXPORT_SYMBOL(_Znaj); ++EXPORT_SYMBOL(ZnwjPv); ++EXPORT_SYMBOL(_ZdlPv); ++EXPORT_SYMBOL(_ZdaPv); ++ +diff -urN linux-2.6.17/arch/mips/brcm-boards/bcm963xx/softdsl/AdslCoreDefs.h linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/softdsl/AdslCoreDefs.h +--- linux-2.6.17/arch/mips/brcm-boards/bcm963xx/softdsl/AdslCoreDefs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/softdsl/AdslCoreDefs.h 2006-08-03 16:36:58.000000000 +0200 +@@ -0,0 +1,2 @@ ++#define ADSL_SDRAM_IMAGE_SIZE (384*1024) ++ +diff -urN linux-2.6.17/arch/mips/brcm-boards/bcm963xx/time.c linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/time.c +--- linux-2.6.17/arch/mips/brcm-boards/bcm963xx/time.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.17-brcm63xx/arch/mips/brcm-boards/bcm963xx/time.c 2006-08-03 16:36:58.000000000 +0200 +@@ -0,0 +1,277 @@ ++/* ++<:copyright-gpl ++ Copyright 2004 Broadcom Corp. All Rights Reserved. ++ ++ This program is free software; you can distribute it and/or modify it ++ under the terms of the GNU General Public License (Version 2) as ++ published by the Free Software Foundation. ++ ++ This program is distributed in the hope it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++:> ++*/ ++/* ++ * Setup time for Broadcom 963xx MIPS boards ++ */ ++ ++#include <linux/config.h> ++#include <linux/init.h> ++#include <linux/kernel_stat.h> ++#include <linux/sched.h> ++#include <linux/spinlock.h> ++#include <linux/interrupt.h> ++#include <linux/module.h> ++#include <linux/time.h> ++#include <linux/timex.h> ++ ++#include <asm/mipsregs.h> ++#include <asm/ptrace.h> ++#include <asm/div64.h> ++#include <asm/time.h> ++ ++#include <bcm_map_part.h> ++#include <bcm_intr.h> ++ ++unsigned long r4k_interval; /* Amount to increment compare reg each time */ ++static unsigned long r4k_cur; /* What counter should be at next timer irq */ ++ ++/* Cycle counter value at the previous timer interrupt.. */ ++static unsigned int timerhi = 0, timerlo = 0; ++ ++extern volatile unsigned long wall_jiffies; ++ ++/* Optional board-specific timer routine */ ++void (*board_timer_interrupt)(int irq, void *dev_id, struct pt_regs * regs); ++ ++static inline void ack_r4ktimer(unsigned long newval) ++{ ++ write_c0_compare(newval); ++} ++ ++/* ++ * There are a lot of conceptually broken versions of the MIPS timer interrupt ++ * handler floating around. This one is rather different, but the algorithm ++ * is provably more robust. ++ */ ++static irqreturn_t brcm_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ++{ ++ unsigned int count; ++ ++ if (r4k_interval == 0) ++ goto null; ++ ++ do { ++ do_timer(regs); ++ ++ if (board_timer_interrupt) ++ board_timer_interrupt(irq, dev_id, regs); ++ ++ r4k_cur += r4k_interval; ++ ack_r4ktimer(r4k_cur); ++ ++ } while (((count = (unsigned long)read_c0_count()) ++ - r4k_cur) < 0x7fffffff); ++ ++ if (!jiffies) { ++ /* ++ * If jiffies has overflowed in this timer_interrupt we must ++ * update the timer[hi]/[lo] to make do_fast_gettimeoffset() ++ * quotient calc still valid. -arca ++ */ ++ timerhi = timerlo = 0; ++ } else { ++ /* ++ * The cycle counter is only 32 bit which is good for about ++ * a minute at current count rates of upto 150MHz or so. ++ */ ++ timerhi += (count < timerlo); /* Wrap around */ ++ timerlo = count; ++ } ++ ++ return IRQ_HANDLED; ++ ++null: ++ ack_r4ktimer(0); ++ return IRQ_NONE; ++} ++ ++static struct irqaction brcm_timer_action = { ++ .handler = brcm_timer_interrupt, ++ .flags = SA_INTERRUPT, ++ .mask = CPU_MASK_NONE, ++ .name = "timer", ++ .next = NULL, ++ .dev_id = brcm_timer_interrupt, ++}; ++ ++ ++void __init brcm_timer_setup(struct irqaction *irq) ++{ ++ r4k_cur = (read_c0_count() + r4k_interval); ++ write_c0_compare(r4k_cur); ++ ++ /* we are using the cpu counter for timer interrupts */ ++ irq->handler = no_action; /* we use our own handler */ ++ setup_irq(MIPS_TIMER_INT, &brcm_timer_action); ++ set_c0_status(IE_IRQ5); ++} ++ ++#if 0 ++/* This is for machines which generate the exact clock. */ ++#define USECS_PER_JIFFY (1000000/HZ) ++#define USECS_PER_JIFFY_FRAC (0x100000000*1000000/HZ&0xffffffff) ++ ++static void call_do_div64_32( unsigned long *res, unsigned int high, ++ unsigned int low, unsigned long base ) ++{ ++ do_div64_32(*res, high, low, base); ++} ++ ++/* ++ * FIXME: Does playing with the RP bit in c0_status interfere with this code? ++ */ ++static unsigned long do_fast_gettimeoffset(void) ++{ ++ u32 count; ++ unsigned long res, tmp; ++ ++ /* Last jiffy when do_fast_gettimeoffset() was called. */ ++ static unsigned long last_jiffies=0; ++ unsigned long quotient; ++ ++ /* ++ * Cached "1/(clocks per usec)*2^32" value. ++ * It has to be recalculated once each jiffy. ++ */ ++ static unsigned long cached_quotient=0; ++ ++ tmp = jiffies; ++ ++ quotient = cached_quotient; ++ ++ if (tmp && last_jiffies != tmp) { ++ last_jiffies = tmp; ++#ifdef CONFIG_CPU_MIPS32 ++ if (last_jiffies != 0) { ++ ++ unsigned long r0; ++ /* gcc 3.0.1 gets an internal compiler error if there are two ++ * do_div64_32 inline macros. To work around this problem, ++ * do_div64_32 is called as a function. ++ */ ++ call_do_div64_32(&r0, timerhi, timerlo, tmp); ++ call_do_div64_32("ient, USECS_PER_JIFFY, ++ USECS_PER_JIFFY_FRAC, r0); ++ ++ cached_quotient = quotient; ++ ++ } ++#else ++ __asm__(".set\tnoreorder\n\t" ++ ".set\tnoat\n\t" ++ ".set\tmips3\n\t" ++ "lwu\t%0,%2\n\t" ++ "dsll32\t$1,%1,0\n\t" ++ "or\t$1,$1,%0\n\t" ++ "ddivu\t$0,$1,%3\n\t" ++ "mflo\t$1\n\t" ++ "dsll32\t%0,%4,0\n\t" ++ "nop\n\t" ++ "ddivu\t$0,%0,$1\n\t" ++ "mflo\t%0\n\t" ++ ".set\tmips0\n\t" ++ ".set\tat\n\t" ++ ".set\treorder" ++ :"=&r" (quotient) ++ :"r" (timerhi), ++ "m" (timerlo), ++ "r" (tmp), ++ "r" (USECS_PER_JIFFY) ++ :"$1"); ++ cached_quotient = quotient; ++#endif ++ } ++ ++ /* Get last timer tick in absolute kernel time */ ++ count = read_c0_count(); ++ ++ /* .. relative to previous jiffy (32 bits is enough) */ ++ count -= timerlo; ++ ++ __asm__("multu\t%1,%2\n\t" ++ "mfhi\t%0" ++ :"=r" (res) ++ :"r" (count), ++ "r" (quotient)); ++ ++ /* ++ * Due to possible jiffies inconsistencies, we need to check ++ * the result so that we'll get a timer that is monotonic. ++ */ ++ if (res >= USECS_PER_JIFFY) ++ res = USECS_PER_JIFFY-1; ++ ++ return res; ++} ++ ++void do_gettimeofday(struct timeval *tv) ++{ ++ unsigned int flags; ++ ++ read_lock_irqsave (&xtime_lock, flags); ++ tv->tv_sec = xtime.tv_sec; ++ tv->tv_usec = xtime.tv_nsec/1000; ++ tv->tv_usec += do_fast_gettimeoffset(); ++ ++ /* ++ * xtime is atomically updated in timer_bh. jiffies - wall_jiffies ++ * is nonzero if the timer bottom half hasnt executed yet. ++ */ ++ if (jiffies - wall_jiffies) ++ tv->tv_usec += USECS_PER_JIFFY; ++ ++ read_unlock_irqrestore (&xtime_lock, flags); ++ ++ if (tv->tv_usec >= 1000000) { ++ tv->tv_usec -= 1000000; ++ tv->tv_sec++; ++ } ++} ++ ++EXPORT_SYMBOL(do_gettimeofday); ++ ++int do_settimeofday(struct timespec *tv) ++{ ++ write_lock_irq (&xtime_lock); ++ ++ /* This is revolting. We need to set the xtime.tv_usec correctly. ++ * However, the value in this location is is value at the last tick. ++ * Discover what correction gettimeofday would have done, and then ++ * undo it! ++ */ ++ tv->tv_nsec -= do_fast_gettimeoffset()*NSEC_PER_USEC; ++ ++ if (tv->tv_nsec < 0) { ++ tv->tv_nsec += 1000000*NSEC_PER_USEC; ++ tv->tv_sec--; ++ } ++ ++ xtime.tv_sec = tv->tv_sec; ++ xtime.tv_nsec = tv->tv_nsec; ++ time_adjust = 0; /* stop active adjtime() */ ++ time_status |= STA_UNSYNC; ++ time_maxerror = NTP_PHASE_LIMIT; ++ time_esterror = NTP_PHASE_LIMIT; ++ ++ write_unlock_irq (&xtime_lock); ++} ++ ++EXPORT_SYMBOL(do_settimeofday); ++ ++#endif +diff -urN linux-2.6.17/arch/mips/brcm-boards/generic/dbg_io.c linux-2.6.17-brcm63xx/arch/mips/brcm-boards/generic/dbg_io.c +--- linux-2.6.17/arch/mips/brcm-boards/generic/dbg_io.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.17-brcm63xx/arch/mips/brcm-boards/generic/dbg_io.c 2006-08-03 16:36:58.000000000 +0200 +@@ -0,0 +1,260 @@ ++/* ++<:copyright-gpl ++ Copyright 2003 Broadcom Corp. All Rights Reserved. ++ ++ This program is free software; you can distribute it and/or modify it ++ under the terms of the GNU General Public License (Version 2) as ++ published by the Free Software Foundation. ++ ++ This program is distributed in the hope it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++:> ++*/ ++ ++#include <linux/config.h> ++#include <linux/tty.h> ++#include <linux/major.h> ++#include <linux/init.h> ++#include <linux/console.h> ++#include <linux/fs.h> ++#include <linux/interrupt.h> ++#include <linux/kernel.h> ++#include <linux/types.h> ++#include <linux/sched.h> ++ ++#include <bcm_map_part.h> ++ ++#undef PRNT /* define for debug printing */ ++ ++#define UART16550_BAUD_2400 2400 ++#define UART16550_BAUD_4800 4800 ++#define UART16550_BAUD_9600 9600 ++#define UART16550_BAUD_19200 19200 ++#define UART16550_BAUD_38400 38400 ++#define UART16550_BAUD_57600 57600 ++#define UART16550_BAUD_115200 115200 ++ ++#define UART16550_PARITY_NONE 0 ++#define UART16550_PARITY_ODD 0x08 ++#define UART16550_PARITY_EVEN 0x18 ++#define UART16550_PARITY_MARK 0x28 ++#define UART16550_PARITY_SPACE 0x38 ++ ++#define UART16550_DATA_5BIT 0x0 ++#define UART16550_DATA_6BIT 0x1 ++#define UART16550_DATA_7BIT 0x2 ++#define UART16550_DATA_8BIT 0x3 ++ ++#define UART16550_STOP_1BIT 0x0 ++#define UART16550_STOP_2BIT 0x4 ++ ++volatile Uart * stUart = UART_BASE; ++ ++#define WRITE16(addr, value) ((*(volatile UINT16 *)((ULONG)&addr)) = value) ++ ++/* Low level UART routines from promcon.c */ ++extern void prom_putc(char c); ++extern char prom_getc(void); ++extern int prom_getc_nowait(void); ++extern int prom_testc(void); ++ ++extern void set_debug_traps(void); ++extern void breakpoint(void); ++extern void enable_brcm_irq(unsigned int); ++extern void set_async_breakpoint(unsigned int epc); ++ ++#ifdef CONFIG_GDB_CONSOLE ++extern void register_gdb_console(void); ++#endif ++ ++int gdb_initialized = 0; ++ ++#define GDB_BUF_SIZE 512 /* power of 2, please */ ++ ++static char gdb_buf[GDB_BUF_SIZE] ; ++static int gdb_buf_in_inx ; ++static atomic_t gdb_buf_in_cnt ; ++static int gdb_buf_out_inx ; ++ ++void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) ++{ ++ /* Do nothing, assume boot loader has already set up serial port */ ++ printk("debugInit called\n"); ++} ++ ++/* ++ * Get a char if available, return -1 if nothing available. ++ * Empty the receive buffer first, then look at the interface hardware. ++ */ ++static int read_char(void) ++{ ++ if (atomic_read(&gdb_buf_in_cnt) != 0) /* intr routine has q'd chars */ ++ { ++ int chr ; ++ ++ chr = gdb_buf[gdb_buf_out_inx++] ; ++ gdb_buf_out_inx &= (GDB_BUF_SIZE - 1) ; ++ atomic_dec(&gdb_buf_in_cnt) ; ++ return(chr) ; ++ } ++ return(prom_getc_nowait()) ; /* read from hardware */ ++} /* read_char */ ++ ++/* ++ * This is the receiver interrupt routine for the GDB stub. ++ * It will receive a limited number of characters of input ++ * from the gdb host machine and save them up in a buffer. ++ * ++ * When the gdb stub routine getDebugChar() is called it ++ * draws characters out of the buffer until it is empty and ++ * then reads directly from the serial port. ++ * ++ * We do not attempt to write chars from the interrupt routine ++ * since the stubs do all of that via putDebugChar() which ++ * writes one byte after waiting for the interface to become ++ * ready. ++ * ++ * The debug stubs like to run with interrupts disabled since, ++ * after all, they run as a consequence of a breakpoint in ++ * the kernel. ++ * ++ * Perhaps someone who knows more about the tty driver than I ++ * care to learn can make this work for any low level serial ++ * driver. ++ */ ++static void gdb_interrupt(int irq, void *dev_id, struct pt_regs * regs) ++{ ++ int chr ; ++ int more; ++ do ++ { ++ chr = prom_getc_nowait() ; ++ more = prom_testc(); ++ if (chr < 0) continue ; ++ ++ /* If we receive a Ctrl-C then this is GDB trying to break in */ ++ if (chr == 3) ++ { ++ /* Replace current instruction with breakpoint */ ++ set_async_breakpoint(regs->cp0_epc); ++ //breakpoint(); ++ } ++ ++#ifdef PRNT ++ printk("gdb_interrupt: chr=%02x '%c', more = %x\n", ++ chr, chr > ' ' && chr < 0x7F ? chr : ' ', more) ; ++#endif ++ ++ if (atomic_read(&gdb_buf_in_cnt) >= GDB_BUF_SIZE) ++ { /* buffer overflow, clear it */ ++ gdb_buf_in_inx = 0 ; ++ atomic_set(&gdb_buf_in_cnt, 0) ; ++ gdb_buf_out_inx = 0 ; ++ break ; ++ } ++ ++ gdb_buf[gdb_buf_in_inx++] = chr ; ++ gdb_buf_in_inx &= (GDB_BUF_SIZE - 1) ; ++ atomic_inc(&gdb_buf_in_cnt) ; ++ } ++ while (more !=0); ++ ++} /* gdb_interrupt */ ++ ++/* ++ * getDebugChar ++ * ++ * This is a GDB stub routine. It waits for a character from the ++ * serial interface and then returns it. If there is no serial ++ * interface connection then it returns a bogus value which will ++ * almost certainly cause the system to hang. ++ */ ++int getDebugChar(void) ++{ ++ volatile int chr ; ++ ++#ifdef PRNT ++ printk("getDebugChar: ") ; ++#endif ++ ++ while ( (chr = read_char()) < 0 ) ; ++ ++#ifdef PRNT ++ printk("%c\n", chr > ' ' && chr < 0x7F ? chr : ' ') ; ++#endif ++ return(chr) ; ++ ++} /* getDebugChar */ ++ ++/* ++ * putDebugChar ++ * ++ * This is a GDB stub routine. It waits until the interface is ready ++ * to transmit a char and then sends it. If there is no serial ++ * interface connection then it simply returns to its caller, having ++ * pretended to send the char. ++ */ ++int putDebugChar(unsigned char chr) ++{ ++#ifdef PRNT ++ printk("putDebugChar: chr=%02x '%c'\n", chr, ++ chr > ' ' && chr < 0x7F ? chr : ' ') ; ++#endif ++ ++ prom_putc(chr) ; /* this routine will wait */ ++ return 1; ++ ++} /* putDebugChar */ ++ ++/* Just a NULL routine for testing. */ ++void gdb_null(void) ++{ ++} ++ ++void rs_kgdb_hook(int tty_no) ++{ ++ printk("rs_kgdb_hook: tty %d\n", tty_no); ++ ++ /* Call GDB routine to setup the exception vectors for the debugger */ ++ set_debug_traps(); ++ ++ printk("Breaking into debugger...\n"); ++ breakpoint(); ++ gdb_null() ; ++ printk("Connected.\n"); ++ ++ gdb_initialized = 1; ++ ++#ifdef CONFIG_GDB_CONSOLE ++ register_gdb_console(); ++#endif ++} ++ ++void kgdb_hook_irq() ++{ ++ int retval ; ++ uint16 uMask; ++ ++ printk("GDB: Hooking UART interrupt\n"); ++ ++ retval = request_irq(INTERRUPT_ID_UART, ++ gdb_interrupt, ++ SA_INTERRUPT, ++ "GDB-stub", NULL); ++ ++ if (retval != 0) ++ printk("gdb_hook: request_irq(irq=%d) failed: %d\n", INTERRUPT_ID_UART, retval); ++ ++ // Enable UART config Rx not empty IRQ ++ uMask = READ16(stUart->intMask) ; ++ // printk("intMask: 0x%x\n", uMask); ++ WRITE16(stUart->intMask, uMask | RXFIFONE); ++} ++ ++ +diff -urN linux-2.6.17/arch/mips/brcm-boards/generic/int-handler.S linux-2.6.17-brcm63xx/arch/mips/brcm-boards/generic/int-handler.S +--- linux-2.6.17/arch/mips/brcm-boards/generic/int-handler.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.17-brcm63xx/arch/mips/brcm-boards/generic/int-handler.S 2006-08-03 16:36:58.000000000 +0200 +@@ -0,0 +1,59 @@ ++/* ++<:copyright-gpl ++ Copyright 2002 Broadcom Corp. All Rights Reserved. ++ ++ This program is free software; you can distribute it and/or modify it ++ under the terms of the GNU General Public License (Version 2) as ++ published by the Free Software Foundation. ++ ++ This program is distributed in the hope it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++:> ++*/ ++/* ++ * Generic interrupt handler for Broadcom MIPS boards ++ */ ++ ++#include <linux/config.h> ++ ++#include <asm/asm.h> ++#include <asm/mipsregs.h> ++#include <asm/regdef.h> ++#include <asm/stackframe.h> ++ ++/* ++ * MIPS IRQ Source ++ * -------- ------ ++ * 0 Software (ignored) ++ * 1 Software (ignored) ++ * 2 Combined hardware interrupt (hw0) ++ * 3 Hardware ++ * 4 Hardware ++ * 5 Hardware ++ * 6 Hardware ++ * 7 R4k timer ++ */ ++ ++ .text ++ .set noreorder ++ .set noat ++ .align 5 ++ NESTED(brcmIRQ, PT_SIZE, sp) ++ SAVE_ALL ++ CLI ++ .set noreorder ++ .set at ++ ++ jal brcm_irq_dispatch ++ move a0, sp ++ ++ j ret_from_irq ++ nop ++ ++ END(brcmIRQ) +diff -urN linux-2.6.17/arch/mips/brcm-boards/generic/Makefile linux-2.6.17-brcm63xx/arch/mips/brcm-boards/generic/Makefile +--- linux-2.6.17/arch/mips/brcm-boards/generic/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.17-brcm63xx/arch/mips/brcm-boards/generic/Makefile 2006-08-03 16:36:58.000000000 +0200 +@@ -0,0 +1,11 @@ ++# ++# Makefile for generic Broadcom MIPS boards ++# ++# Copyright (C) 2001 Broadcom Corporation ++# ++obj-y := int-handler.o ++ ++ifdef CONFIG_REMOTE_DEBUG ++obj-y += dbg_io.o ++endif ++ |