source: trunk/target/linux/brcm47xx/patches-3.2/820-wgt634u-nvram-fix.patch @ 30943

Last change on this file since 30943 was 30943, checked in by hauke, 4 years ago

brcm47xx: add support for NAND flash on devices using bcma

This patch add support for the NAND flash on BCM5357 based devices like the WNR3500Lv2.

Thank you Tathagata Das <tathagata@…> for the patch

File size: 7.6 KB
  • arch/mips/bcm47xx/Makefile

    The Netgear wgt634u uses a different format for storing the 
    configuration. This patch is needed to read out the correct 
    configuration. The cfe_env.c file uses a different method way to read 
    out the configuration than the in kernel cfe config reader.
    
    a b  
    33# under Linux. 
    44# 
    55 
    6 obj-y                           += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o bus.o sprom.o 
     6obj-y                           += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o bus.o sprom.o cfe_env.o 
  • new file arch/mips/bcm47xx/cfe_env.c

    - +  
     1/* 
     2 * CFE environment variable access 
     3 * 
     4 * Copyright 2001-2003, Broadcom Corporation 
     5 * Copyright 2006, Felix Fietkau <nbd@openwrt.org> 
     6 *  
     7 * This program is free software; you can redistribute  it and/or modify it 
     8 * under  the terms of  the GNU General  Public License as published by the 
     9 * Free Software Foundation;  either version 2 of the  License, or (at your 
     10 * option) any later version. 
     11 */ 
     12 
     13#include <linux/init.h> 
     14#include <linux/module.h> 
     15#include <linux/kernel.h> 
     16#include <linux/string.h> 
     17#include <asm/io.h> 
     18#include <asm/uaccess.h> 
     19 
     20#define NVRAM_SIZE       (0x1ff0) 
     21static char _nvdata[NVRAM_SIZE]; 
     22static char _valuestr[256]; 
     23 
     24/* 
     25 * TLV types.  These codes are used in the "type-length-value" 
     26 * encoding of the items stored in the NVRAM device (flash or EEPROM) 
     27 * 
     28 * The layout of the flash/nvram is as follows: 
     29 * 
     30 * <type> <length> <data ...> <type> <length> <data ...> <type_end> 
     31 * 
     32 * The type code of "ENV_TLV_TYPE_END" marks the end of the list. 
     33 * The "length" field marks the length of the data section, not 
     34 * including the type and length fields. 
     35 * 
     36 * Environment variables are stored as follows: 
     37 * 
     38 * <type_env> <length> <flags> <name> = <value> 
     39 * 
     40 * If bit 0 (low bit) is set, the length is an 8-bit value. 
     41 * If bit 0 (low bit) is clear, the length is a 16-bit value 
     42 *  
     43 * Bit 7 set indicates "user" TLVs.  In this case, bit 0 still 
     44 * indicates the size of the length field.   
     45 * 
     46 * Flags are from the constants below: 
     47 * 
     48 */ 
     49#define ENV_LENGTH_16BITS       0x00    /* for low bit */ 
     50#define ENV_LENGTH_8BITS        0x01 
     51 
     52#define ENV_TYPE_USER           0x80 
     53 
     54#define ENV_CODE_SYS(n,l) (((n)<<1)|(l)) 
     55#define ENV_CODE_USER(n,l) ((((n)<<1)|(l)) | ENV_TYPE_USER) 
     56 
     57/* 
     58 * The actual TLV types we support 
     59 */ 
     60 
     61#define ENV_TLV_TYPE_END        0x00     
     62#define ENV_TLV_TYPE_ENV        ENV_CODE_SYS(0,ENV_LENGTH_8BITS) 
     63 
     64/* 
     65 * Environment variable flags  
     66 */ 
     67 
     68#define ENV_FLG_NORMAL          0x00    /* normal read/write */ 
     69#define ENV_FLG_BUILTIN         0x01    /* builtin - not stored in flash */ 
     70#define ENV_FLG_READONLY        0x02    /* read-only - cannot be changed */ 
     71 
     72#define ENV_FLG_MASK            0xFF    /* mask of attributes we keep */ 
     73#define ENV_FLG_ADMIN           0x100   /* lets us internally override permissions */ 
     74 
     75 
     76/*  ********************************************************************* 
     77    *  _nvram_read(buffer,offset,length) 
     78    *   
     79    *  Read data from the NVRAM device 
     80    *   
     81    *  Input parameters:  
     82    *      buffer - destination buffer 
     83    *      offset - offset of data to read 
     84    *      length - number of bytes to read 
     85    *       
     86    *  Return value: 
     87    *      number of bytes read, or <0 if error occured 
     88    ********************************************************************* */ 
     89static int 
     90_nvram_read(unsigned char *nv_buf, unsigned char *buffer, int offset, int length) 
     91{ 
     92    int i; 
     93    if (offset > NVRAM_SIZE) 
     94        return -1;  
     95 
     96    for ( i = 0; i < length; i++) { 
     97        buffer[i] = ((volatile unsigned char*)nv_buf)[offset + i]; 
     98    } 
     99    return length; 
     100} 
     101 
     102 
     103static char* 
     104_strnchr(const char *dest,int c,size_t cnt) 
     105{ 
     106        while (*dest && (cnt > 0)) { 
     107        if (*dest == c) return (char *) dest; 
     108        dest++; 
     109        cnt--; 
     110        } 
     111        return NULL; 
     112} 
     113 
     114 
     115 
     116/* 
     117 * Core support API: Externally visible. 
     118 */ 
     119 
     120/* 
     121 * Get the value of an NVRAM variable 
     122 * @param       name    name of variable to get 
     123 * @return      value of variable or NULL if undefined 
     124 */ 
     125 
     126char*  
     127cfe_env_get(unsigned char *nv_buf, char* name) 
     128{ 
     129    int size; 
     130    unsigned char *buffer; 
     131    unsigned char *ptr; 
     132    unsigned char *envval; 
     133    unsigned int reclen; 
     134    unsigned int rectype; 
     135    int offset; 
     136    int flg; 
     137     
     138        if (!strcmp(name, "nvram_type")) 
     139                return "cfe"; 
     140         
     141    size = NVRAM_SIZE; 
     142    buffer = &_nvdata[0]; 
     143 
     144    ptr = buffer; 
     145    offset = 0; 
     146 
     147    /* Read the record type and length */ 
     148    if (_nvram_read(nv_buf, ptr,offset,1) != 1) { 
     149        goto error; 
     150    } 
     151     
     152    while ((*ptr != ENV_TLV_TYPE_END)  && (size > 1)) { 
     153 
     154        /* Adjust pointer for TLV type */ 
     155        rectype = *(ptr); 
     156        offset++; 
     157        size--; 
     158 
     159        /*  
     160         * Read the length.  It can be either 1 or 2 bytes 
     161         * depending on the code  
     162         */ 
     163        if (rectype & ENV_LENGTH_8BITS) { 
     164            /* Read the record type and length - 8 bits */ 
     165            if (_nvram_read(nv_buf, ptr,offset,1) != 1) { 
     166                goto error; 
     167            } 
     168            reclen = *(ptr); 
     169            size--; 
     170            offset++; 
     171        } 
     172        else { 
     173            /* Read the record type and length - 16 bits, MSB first */ 
     174            if (_nvram_read(nv_buf, ptr,offset,2) != 2) { 
     175                goto error; 
     176            } 
     177            reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1); 
     178            size -= 2; 
     179            offset += 2; 
     180        } 
     181 
     182        if (reclen > size) 
     183            break;      /* should not happen, bad NVRAM */ 
     184 
     185        switch (rectype) { 
     186            case ENV_TLV_TYPE_ENV: 
     187                /* Read the TLV data */ 
     188                if (_nvram_read(nv_buf, ptr,offset,reclen) != reclen) 
     189                    goto error; 
     190                flg = *ptr++; 
     191                envval = (unsigned char *) _strnchr(ptr,'=',(reclen-1)); 
     192                if (envval) { 
     193                    *envval++ = '\0'; 
     194                    memcpy(_valuestr,envval,(reclen-1)-(envval-ptr)); 
     195                    _valuestr[(reclen-1)-(envval-ptr)] = '\0'; 
     196#if 0                    
     197                    printk(KERN_INFO "NVRAM:%s=%s\n", ptr, _valuestr); 
     198#endif 
     199                    if(!strcmp(ptr, name)){ 
     200                        return _valuestr; 
     201                    } 
     202                    if((strlen(ptr) > 1) && !strcmp(&ptr[1], name)) 
     203                        return _valuestr; 
     204                } 
     205                break; 
     206                 
     207            default:  
     208                /* Unknown TLV type, skip it. */ 
     209                break; 
     210            } 
     211 
     212        /* 
     213         * Advance to next TLV  
     214         */ 
     215                 
     216        size -= (int)reclen; 
     217        offset += reclen; 
     218 
     219        /* Read the next record type */ 
     220        ptr = buffer; 
     221        if (_nvram_read(nv_buf, ptr,offset,1) != 1) 
     222            goto error; 
     223        } 
     224 
     225error: 
     226    return NULL; 
     227 
     228} 
     229 
  • arch/mips/bcm47xx/nvram.c

    a b  
    2525#include <linux/mtd/bcm47xx_nand.h> 
    2626 
    2727static char nvram_buf[NVRAM_SPACE]; 
     28static int cfe_env; 
     29extern char *cfe_env_get(char *nv_buf, const char *name); 
    2830 
    2931/* Probe for NVRAM header */ 
    3032static void early_nvram_init_pflash(void) 
    static void early_nvram_init_pflash(void 
    6163                break; 
    6264#endif 
    6365        } 
     66        cfe_env = 0; 
     67 
     68        /* XXX: hack for supporting the CFE environment stuff on WGT634U */ 
     69        if (lim >= 8 * 1024 * 1024) { 
     70                src = (u32 *) KSEG1ADDR(base + 8 * 1024 * 1024 - 0x2000); 
     71                dst = (u32 *) nvram_buf; 
     72 
     73                if ((*src & 0xff00ff) == 0x000001) { 
     74                        printk("early_nvram_init: WGT634U NVRAM found.\n"); 
     75 
     76                        for (i = 0; i < 0x1ff0; i++) { 
     77                                if (*src == 0xFFFFFFFF) 
     78                                        break; 
     79                                *dst++ = *src++; 
     80                        } 
     81                        cfe_env = 1; 
     82                        return; 
     83                } 
     84        } 
    6485 
    6586        off = FLASH_MIN; 
    6687        while (off <= lim) { 
    int nvram_getenv(char *name, char *val, 
    232253        if (!nvram_buf[0]) 
    233254                early_nvram_init(); 
    234255 
     256        if (cfe_env) { 
     257                value = cfe_env_get(nvram_buf, name); 
     258                snprintf(val, val_len, "%s", value); 
     259                return 0; 
     260        } 
     261 
    235262        /* Look for name=value and return value */ 
    236263        var = &nvram_buf[sizeof(struct nvram_header)]; 
    237264        end = nvram_buf + sizeof(nvram_buf) - 2; 
    char *nvram_get(const char *name) 
    260287        if (!nvram_buf[0]) 
    261288                early_nvram_init(); 
    262289 
     290        if (cfe_env) 
     291                return cfe_env_get(nvram_buf, name); 
     292 
    263293        /* Look for name=value and return value */ 
    264294        var = &nvram_buf[sizeof(struct nvram_header)]; 
    265295        end = nvram_buf + sizeof(nvram_buf) - 2; 
Note: See TracBrowser for help on using the repository browser.