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 +#include +#include +#include +#include +#include + +#include +#include +#define BCMTAG_EXE_USE +#include +#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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#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 ); +} + +//<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; +} +//< 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 + + +#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 +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 +#include +#include +#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= 0; i--) { + for(j=0; j 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +extern void brcm_timer_setup(struct irqaction *irq); +extern unsigned long getMemorySize(void); + +#if defined(CONFIG_BCM96348) && defined(CONFIG_PCI) +#include +#include +#include +#include + +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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#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 + +#include +#include +#include +#include + +/* + * 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 +