Exemplo n.º 1
0
int
nvram_set(const char *name, const char *value)
{
	unsigned long flags;
	struct nvram_header *header;
	int ret;

	if (!name)
		return -EINVAL;

	// Check early write
	if (nvram_major < 0)
		return 0;

	spin_lock_irqsave(&nvram_lock, flags);
	if ((ret = _nvram_set(name, value))) {
		/* Consolidate space and try again */
		if ((header = kmalloc(NVRAM_SPACE, GFP_ATOMIC))) {
			if (_nvram_commit(header) == 0) {
				ret = _nvram_set(name, value);
			}
			kfree(header);
		}
	}
	spin_unlock_irqrestore(&nvram_lock, flags);

	return ret;
}
Exemplo n.º 2
0
int
BCMINITFN(nvram_commit_internal)(bool nvram_corrupt)
{
	struct nvram_header *header;
	int ret;
	uint32 *src, *dst;
	uint i;

	if (!(header = (struct nvram_header *) MALLOC(NULL, MAX_NVRAM_SPACE))) {
		printf("nvram_commit: out of memory\n");
		return -12; /* -ENOMEM */
	}

	NVRAM_LOCK();

	/* Regenerate NVRAM */
	ret = _nvram_commit(header);
	if (ret)
		goto done;

	src = (uint32 *) &header[1];
	dst = src;

	for (i = sizeof(struct nvram_header); i < header->len && i < MAX_NVRAM_SPACE; i += 4)
		*dst++ = htol32(*src++);

#ifdef _CFE_
	if ((ret = cfe_open(flashdrv_nvram)) >= 0) {
		if (nvram_corrupt) {
			printf("Corrupting NVRAM...\n");
			header->magic = NVRAM_INVALID_MAGIC;
		}
		cfe_writeblk(ret, 0, (unsigned char *) header, header->len);
		cfe_close(ret);
	}
#else
	if (sysFlashInit(NULL) == 0) {
		/* set/write invalid MAGIC # (in case writing image fails/is interrupted)
		 * write the NVRAM image to flash(with invalid magic)
		 * set/write valid MAGIC #
		 */
		header->magic = NVRAM_CLEAR_MAGIC;
		nvWriteChars((unsigned char *)&header->magic, sizeof(header->magic));

		header->magic = NVRAM_INVALID_MAGIC;
		nvWrite((unsigned short *) header, MAX_NVRAM_SPACE);

		header->magic = NVRAM_MAGIC;
		nvWriteChars((unsigned char *)&header->magic, sizeof(header->magic));
	}
#endif /* ifdef _CFE_ */

done:
	NVRAM_UNLOCK();
	MFREE(NULL, header, MAX_NVRAM_SPACE);
	return ret;
}
Exemplo n.º 3
0
int nvram_commit(void)
{
	LOCK_NVRAM();
	int stat=0;
	if(!(_nvram!=NULL)) _nvram =  _lib_nvram_open_staging();
	stat= _nvram_commit(_nvram);
	stat = staging_to_nvram();
	UNLOCK_NVRAM();
	return stat;
}
Exemplo n.º 4
0
int
nvram_commit(void)
{
    struct nvram_header *header;
    int ret;
    uint32 *src, *dst;
    uint i;
    uint32 err_addr;
    
    if (!(header = (struct nvram_header *) MALLOC(NULL, NVRAM_SPACE))) {
        printf("nvram_commit: out of memory\n");
        return -12;
    }
    
    NVRAM_LOCK();
    ret = _nvram_commit(header);
    
    if (ret)
        goto done;
    
    src = (uint32 *) &header[1];
    dst = src;
    
    for (i = sizeof(struct nvram_header); i < header->len && i < NVRAM_SPACE;
         i += 4)
        *dst++ = htol32(*src++);
    
    
    if (sysFlashInit(NULL) == 0) {
        /* set/write invalid MAGIC # (in case writing image fails/is interrupted)
         * write the NVRAM image to flash(with invalid magic)
         * set/write valid MAGIC #
         */
        header->magic = NVRAM_CLEAR_MAGIC;
        nvWriteChars((unsigned char *)&header->magic, sizeof(header->magic));
        
        header->magic = NVRAM_INVALID_MAGIC;
        nvWrite((unsigned short *) header, NVRAM_SPACE);
        
        header->magic = NVRAM_MAGIC;
        nvWriteChars((unsigned char *)&header->magic, sizeof(header->magic));
    }
    
done:
    NVRAM_UNLOCK();
    MFREE(NULL, header, NVRAM_SPACE);
    return ret;
}
Exemplo n.º 5
0
int
nvram_set(const char *name, const char *value)
{
	unsigned long flags;
	int ret;
	struct nvram_header *header;

	spin_lock_irqsave(&nvram_lock, flags);
#ifdef CFE_UPDATE //write back to default sector as well, Chen-I
        if(strncmp(name, CFE_NVRAM_PREFIX, strlen(CFE_NVRAM_PREFIX))==0)
        {
                if(strcmp(name, CFE_NVRAM_COMMIT)==0)
		{
#ifdef CONFIG_MTD_NFLASH
			spin_unlock_irqrestore(&nvram_lock, flags);
			return cfe_commit();
#else
			cfe_commit();
#endif
		}
                else if(strcmp(name, "asuscfe_dump") == 0)
                        ret = cfe_dump();
                else if(strcmp(name, CFE_NVRAM_WATCHDOG)==0)
                {
                        bcm947xx_watchdog_disable();
                }
                else
                {
                        cfe_update(name+strlen(CFE_NVRAM_PREFIX), value);
                        _nvram_set(name+strlen(CFE_NVRAM_PREFIX), value);
                }
        }
        else
#endif
	if ((ret = _nvram_set(name, value))) {
		printk( KERN_INFO "nvram: consolidating space!\n");
		/* Consolidate space and try again */
		if ((header = kmalloc(nvram_space, GFP_ATOMIC))) {
			if (_nvram_commit(header) == 0)
				ret = _nvram_set(name, value);
			kfree(header);
		}
	}
	spin_unlock_irqrestore(&nvram_lock, flags);

	return ret;
}
Exemplo n.º 6
0
int
nvram_nflash_commit(void)
{
	char *buf;
	size_t len, magic_len;
	unsigned int i;
	int ret;
	struct nvram_header *header;
	unsigned long flags;
	u_int32_t offset;
	struct erase_info erase;

	if (!(buf = kmalloc(NVRAM_SPACE, GFP_KERNEL))) {
		printk("nvram_commit: out of memory\n");
		return -ENOMEM;
	}

	down(&nvram_sem);

	offset = 0;
	header = (struct nvram_header *)buf;
	header->magic = NVRAM_MAGIC;
	/* reset MAGIC before we regenerate the NVRAM,
	 * otherwise we'll have an incorrect CRC
	 */
	/* Regenerate NVRAM */
	spin_lock_irqsave(&nvram_lock, flags);
	ret = _nvram_commit(header);
	spin_unlock_irqrestore(&nvram_lock, flags);
	if (ret)
		goto done;

	/* Write partition up to end of data area */
	i = header->len;
	ret = nvram_mtd->write(nvram_mtd, offset, i, &len, buf);
	if (ret || len != i) {
		printk("nvram_commit: write error\n");
		ret = -EIO;
		goto done;
	}

done:
	up(&nvram_sem);
	kfree(buf);
	return ret;
}
Exemplo n.º 7
0
int
nvram_commit(void)
{
	struct nvram_header *header;
	int ret;
	uint32 *src, *dst;
	uint i;

	if (!(header = (struct nvram_header *) MALLOC(NVRAM_SPACE))) {
		printf("nvram_commit: out of memory\n");
		return -12; /* -ENOMEM */
	}

	NVRAM_LOCK();

	/* Regenerate NVRAM */
	ret = _nvram_commit(header);
	if (ret)
		goto done;
	
	src = (uint32 *) &header[1];
	dst = src;

	for (i = sizeof(struct nvram_header); i < header->len && i < NVRAM_SPACE; i += 4)
		*dst++ = htol32(*src++);
#ifdef ASUS
#else
#ifdef _CFE_
	if ((ret = cfe_open("flash0.nvram")) >= 0) {
		cfe_writeblk(ret, 0, (unsigned char *) header, NVRAM_SPACE);
		cfe_close(ret);
	}
#else
	if (flash_init((void *) FLASH_BASE, NULL) == 0)
		nvWrite((unsigned short *) header, NVRAM_SPACE);
#endif
#endif

 done:
	NVRAM_UNLOCK();
	MFREE(header, NVRAM_SPACE);
	return ret;
}
Exemplo n.º 8
0
int
BCMINITFN(nvram_reinit_hash)(void)
{
	struct nvram_header *header;
	int ret;

	if (!(header = (struct nvram_header *) MALLOC(NULL, MAX_NVRAM_SPACE))) {
		printf("nvram_reinit_hash: out of memory\n");
		return -12; /* -ENOMEM */
	}

	NVRAM_LOCK();

	/* Regenerate NVRAM */
	ret = _nvram_commit(header);

	NVRAM_UNLOCK();
	MFREE(NULL, header, MAX_NVRAM_SPACE);
	return ret;
}
Exemplo n.º 9
0
int
nvram_set(const char *name, const char *value)
{
	unsigned long flags;
	int ret;
	struct nvram_header *header;

	spin_lock_irqsave(&nvram_lock, flags);
	if ((ret = _nvram_set(name, value))) {
		printk( KERN_INFO "nvram: consolidating space!\n");
		/* Consolidate space and try again */
		if ((header = kmalloc(nvram_space, GFP_ATOMIC))) {
			if (_nvram_commit(header) == 0)
				ret = _nvram_set(name, value);
			kfree(header);
		}
	}
	spin_unlock_irqrestore(&nvram_lock, flags);

	return ret;
}
Exemplo n.º 10
0
int
nvram_commit(void)
{
	unsigned long flags;
	unsigned char *buf;
	int ret;
	
	// Check early commit
	if (nvram_major < 0)
		return 0;
	
	if (!(buf = kmalloc(NVRAM_SPACE, GFP_KERNEL))) {
		printk("nvram_commit: out of memory\n");
		return -ENOMEM;
	}
	
	/* Regenerate NVRAM */
	spin_lock_irqsave(&nvram_lock, flags);
	ret = _nvram_commit((struct nvram_header *)buf);
	spin_unlock_irqrestore(&nvram_lock, flags);
	if (ret)
		goto done;
	
	mutex_lock(&nvram_sem);
	
	/* Write partition up to end of data area */
	ret = ra_mtd_write_nm(MTD_NVRAM_NAME, NVRAM_MTD_OFFSET, NVRAM_SPACE, buf);
	if (ret) {
		printk("nvram_commit: write error\n");
	}
	
	mutex_unlock(&nvram_sem);
	
 done:
	
	kfree(buf);
	return ret;
}
Exemplo n.º 11
0
int
nvram_commit(void)
{
#if 0
	char *buf;
#endif
	size_t erasesize, len, magic_len;
	unsigned int i;
	int ret;
	struct nvram_header *header;
	unsigned long flags;
	u_int32_t offset;
	DECLARE_WAITQUEUE(wait, current);
	wait_queue_head_t wait_q;
	struct erase_info erase;
	u_int32_t magic_offset = 0; /* Offset for writing MAGIC # */
	u_int32_t nvramlen;

	if (!nvram_mtd) {
		printk("nvram_commit: NVRAM not found\n");
		return -ENODEV;
	}

	if (in_interrupt()) {
		printk("nvram_commit: not committing in interrupt\n");
		return -EINVAL;
	}

#ifdef NFLASH_SUPPORT
	if (nvram_mtd->type == MTD_NANDFLASH)
		return nvram_nflash_commit();
#endif
	/* Backup sector blocks to be erased */
	erasesize = ROUNDUP(nvram_space, nvram_mtd->erasesize);
#if 0
	if (!(buf = kmalloc(erasesize, GFP_KERNEL))) {
		printk("nvram_commit: out of memory\n");
		return -ENOMEM;
	}
#endif
	down(&nvram_sem);

	if ((i = erasesize - nvram_space) > 0) {
		offset = nvram_mtd->size - erasesize;
		len = 0;
		ret = nvram_mtd->read(nvram_mtd, offset, i, &len, nvram_commit_buf);
		if (ret || len != i) {
			printk("nvram_commit: read error ret = %d, len = %d/%d\n", ret, len, i);
			ret = -EIO;
			goto done;
		}
		header = (struct nvram_header *)(nvram_commit_buf + i);
		magic_offset = i + ((void *)&header->magic - (void *)header);
	} else {
		offset = nvram_mtd->size - nvram_space;
		magic_offset = ((void *)&header->magic - (void *)header);
		header = (struct nvram_header *)nvram_commit_buf;
	}

	/* clear the existing magic # to mark the NVRAM as unusable
	 * we can pull MAGIC bits low without erase
	 */
	header->magic = NVRAM_CLEAR_MAGIC; /* All zeros magic */
	/* Unlock sector blocks */
	if (nvram_mtd->unlock)
		nvram_mtd->unlock(nvram_mtd, offset, nvram_mtd->erasesize);
	ret = nvram_mtd->write(nvram_mtd, offset + magic_offset, sizeof(header->magic),
		&magic_len, (char *)&header->magic);
	if (ret || magic_len != sizeof(header->magic)) {
		printk("nvram_commit: clear MAGIC error\n");
		ret = -EIO;
		goto done;
	}

	header->magic = NVRAM_MAGIC;
	/* reset MAGIC before we regenerate the NVRAM,
	 * otherwise we'll have an incorrect CRC
	 */
	/* Regenerate NVRAM */
	spin_lock_irqsave(&nvram_lock, flags);
	ret = _nvram_commit(header);
	spin_unlock_irqrestore(&nvram_lock, flags);
	if (ret)
		goto done;

#ifdef NVRAM2HANDLER
	nvramlen = header->len + find_next_header_len(header);
	//printk("nvramlen: %x\n", nvramlen);
#else
	nvramlen = header->len;
#endif

	/* Erase sector blocks */
	init_waitqueue_head(&wait_q);
	for (; offset < nvram_mtd->size - nvram_space + nvramlen;
		offset += nvram_mtd->erasesize) {
		erase.mtd = nvram_mtd;
		erase.addr = offset;
		erase.len = nvram_mtd->erasesize;
		erase.callback = erase_callback;
		erase.priv = (u_long) &wait_q;

		set_current_state(TASK_INTERRUPTIBLE);
		add_wait_queue(&wait_q, &wait);

		/* Unlock sector blocks */
		if (nvram_mtd->unlock)
			nvram_mtd->unlock(nvram_mtd, offset, nvram_mtd->erasesize);

		if ((ret = nvram_mtd->erase(nvram_mtd, &erase))) {
			set_current_state(TASK_RUNNING);
			remove_wait_queue(&wait_q, &wait);
			printk("nvram_commit: erase error\n");
			goto done;
		}

		/* Wait for erase to finish */
		schedule();
		remove_wait_queue(&wait_q, &wait);
	}

	/* Write partition up to end of data area */
	header->magic = NVRAM_INVALID_MAGIC; /* All ones magic */
	offset = nvram_mtd->size - erasesize;
	i = erasesize - nvram_space + nvramlen;
	ret = nvram_mtd->write(nvram_mtd, offset, i, &len, nvram_commit_buf);
	if (ret || len != i) {
		printk("nvram_commit: write error\n");
		ret = -EIO;
		goto done;
	}

	/* Now mark the NVRAM in flash as "valid" by setting the correct
	 * MAGIC #
	 */
	header->magic = NVRAM_MAGIC;
	ret = nvram_mtd->write(nvram_mtd, offset + magic_offset, sizeof(header->magic),
		&magic_len, (char *)&header->magic);
	if (ret || magic_len != sizeof(header->magic)) {
		printk("nvram_commit: write MAGIC error\n");
		ret = -EIO;
		goto done;
	}

	offset = nvram_mtd->size - erasesize;
	ret = nvram_mtd->read(nvram_mtd, offset, 4, &len, nvram_commit_buf);

#ifdef RTN66U_NVRAM_64K_SUPPORT /*Only for RT-N66U upgrade from nvram 32K -> 64K*/
        if(nvramlen<0x8001){
                char *log_buf;
                u_int32_t offset_t;
                size_t log_len;

                offset_t = 0x18000;
                log_buf =0x01020304;
                ret = nvram_mtd->write(nvram_mtd, offset_t, sizeof(log_buf), &log_len, &log_buf);
        }
#endif

done:
	up(&nvram_sem);
#if 0
	kfree(buf);
#endif
	return ret;
}
Exemplo n.º 12
0
int
_nvram_read(char *buf)
{
	struct nvram_header *header = (struct nvram_header *) buf;
	size_t len;
	int offset = 0;

	if (nvram_mtd) {
#ifdef NFLASH_SUPPORT
		if (nvram_mtd->type == MTD_NANDFLASH)
			offset = 0;
		else
#endif
			offset = nvram_mtd->size - nvram_space;
	}

#ifdef RTN66U_NVRAM_64K_SUPPORT /*Only for RT-N66U upgrade from nvram 32K -> 64K*/
	if (nvram_32_reset==1 || 
	    !nvram_mtd ||
            nvram_mtd->read(nvram_mtd, offset, nvram_space, &len, buf) ||
            len != nvram_space ||
	    header->magic != NVRAM_MAGIC) {
		nvram_32_reset=0;
#else
	if (nvram_inram || !nvram_mtd ||
	    nvram_mtd->read(nvram_mtd, offset, nvram_space, &len, buf) ||
	    len != nvram_space ||
	    header->magic != NVRAM_MAGIC) {
#endif
		/* Maybe we can recover some data from early initialization */
		if (nvram_inram)
			printk("Sourcing NVRAM from ram\n");
		memcpy(buf, nvram_buf, nvram_space);
	}

	return 0;
}

struct nvram_tuple *
_nvram_realloc(struct nvram_tuple *t, const char *name, const char *value)
{
	if ((nvram_offset + strlen(value) + 1) > nvram_space)
		return NULL;

	if (!t) {
		if (!(t = kmalloc(sizeof(struct nvram_tuple) + strlen(name) + 1, GFP_ATOMIC)))
			return NULL;

		/* Copy name */
		t->name = (char *) &t[1];
		strcpy(t->name, name);

		t->value = NULL;
	}

	/* Copy value */
	if (!t->value || strcmp(t->value, value)) {
		t->value = &nvram_buf[nvram_offset];
		strcpy(t->value, value);
		nvram_offset += strlen(value) + 1;
	}

	return t;
}

void
_nvram_free(struct nvram_tuple *t)
{
	if (!t)
		nvram_offset = 0;
	else
		kfree(t);
}

int
nvram_init(void *sih)
{
	return 0;
}

int
nvram_set(const char *name, const char *value)
{
	unsigned long flags;
	int ret;
	struct nvram_header *header;

	spin_lock_irqsave(&nvram_lock, flags);

#ifdef CFE_UPDATE //write back to default sector as well, Chen-I
        if(strncmp(name, CFE_NVRAM_PREFIX, strlen(CFE_NVRAM_PREFIX))==0)
        {
                if(strcmp(name, CFE_NVRAM_COMMIT)==0)
                        cfe_commit();
                else if(strcmp(name, "asuscfe_dump") == 0)
                        ret = cfe_dump();
                else if(strcmp(name, CFE_NVRAM_WATCHDOG)==0)
                {
                        bcm947xx_watchdog_disable();
                }
                else
                {
                        cfe_update(name+strlen(CFE_NVRAM_PREFIX), value);
                        _nvram_set(name+strlen(CFE_NVRAM_PREFIX), value);
                }
        }
        else
#endif
	if ((ret = _nvram_set(name, value))) {
		/* Consolidate space and try again */
		if ((header = kmalloc(nvram_space, GFP_ATOMIC))) {
			if (_nvram_commit(header) == 0)
				ret = _nvram_set(name, value);
			kfree(header);
		}
	}
	spin_unlock_irqrestore(&nvram_lock, flags);

	return ret;
}
Exemplo n.º 13
0
int
nvram_commit(void)
{
	char *buf;
	size_t erasesize, len, magic_len;
	unsigned int i;
	int ret;
	struct nvram_header *header;
	unsigned long flags;
	u_int32_t offset;
	DECLARE_WAITQUEUE(wait, current);
	wait_queue_head_t wait_q;
	struct erase_info erase;
	u_int32_t magic_offset = 0; /* Offset for writing MAGIC # */

	if (!nvram_mtd) {
		printk("nvram_commit: NVRAM not found\n");
		return -ENODEV;
	}

	if (in_interrupt()) {
		printk("nvram_commit: not committing in interrupt\n");
		return -EINVAL;
	}

	/* Backup sector blocks to be erased */
	erasesize = ROUNDUP(NVRAM_SPACE, nvram_mtd->erasesize);
	if (!(buf = kmalloc(erasesize, GFP_KERNEL))) {
		printk("nvram_commit: out of memory\n");
		return -ENOMEM;
	}

	down(&nvram_sem);

	if ((i = erasesize - NVRAM_SPACE) > 0) {
		offset = nvram_mtd->size - erasesize;
		len = 0;
		ret = MTD_READ(nvram_mtd, offset, i, &len, buf);
		if (ret || len != i) {
			printk("nvram_commit: read error ret = %d, len = %d/%d\n", ret, len, i);
			ret = -EIO;
			goto done;
		}
		header = (struct nvram_header *)(buf + i);
		magic_offset = i + ((void *)&header->magic - (void *)header);
	} else {
		offset = nvram_mtd->size - NVRAM_SPACE;
		magic_offset = ((void *)&header->magic - (void *)header);
		header = (struct nvram_header *)buf;
	}

	/* clear the existing magic # to mark the NVRAM as unusable 
		 we can pull MAGIC bits low without erase	*/
	header->magic = NVRAM_CLEAR_MAGIC; /* All zeros magic */

	/* Unlock sector blocks (for Intel 28F320C3B flash) , 20060309 */
	if(nvram_mtd->unlock)
		nvram_mtd->unlock(nvram_mtd, offset, nvram_mtd->erasesize);

	ret = MTD_WRITE(nvram_mtd, offset + magic_offset, sizeof(header->magic), 
									&magic_len, (char *)&header->magic);
	if (ret || magic_len != sizeof(header->magic)) {
		printk("nvram_commit: clear MAGIC error\n");
		ret = -EIO;
		goto done;
	}

	header->magic = NVRAM_MAGIC; /* reset MAGIC before we regenerate the NVRAM,
																otherwise we'll have an incorrect CRC */
	/* Regenerate NVRAM */
	spin_lock_irqsave(&nvram_lock, flags);
	ret = _nvram_commit(header);
	spin_unlock_irqrestore(&nvram_lock, flags);
	if (ret)
		goto done;

	/* Erase sector blocks */
	init_waitqueue_head(&wait_q);
	for (; offset < nvram_mtd->size - NVRAM_SPACE + header->len; offset += nvram_mtd->erasesize) {
		erase.mtd = nvram_mtd;
		erase.addr = offset;
		erase.len = nvram_mtd->erasesize;
		erase.callback = erase_callback;
		erase.priv = (u_long) &wait_q;

		set_current_state(TASK_INTERRUPTIBLE);
		add_wait_queue(&wait_q, &wait);

		/* Unlock sector blocks */
		if (nvram_mtd->unlock)
			nvram_mtd->unlock(nvram_mtd, offset, nvram_mtd->erasesize);

		if ((ret = MTD_ERASE(nvram_mtd, &erase))) {
			set_current_state(TASK_RUNNING);
			remove_wait_queue(&wait_q, &wait);
			printk("nvram_commit: erase error\n");
			goto done;
		}

		/* Wait for erase to finish */
		schedule();
		remove_wait_queue(&wait_q, &wait);
	}

	/* Write partition up to end of data area */
	header->magic = NVRAM_INVALID_MAGIC; /* All ones magic */
	offset = nvram_mtd->size - erasesize;
	i = erasesize - NVRAM_SPACE + header->len;
	ret = MTD_WRITE(nvram_mtd, offset, i, &len, buf);
	if (ret || len != i) {
		printk("nvram_commit: write error\n");
		ret = -EIO;
		goto done;
	}

	/* Now mark the NVRAM in flash as "valid" by setting the correct
		 MAGIC # */
	header->magic = NVRAM_MAGIC;
	ret = MTD_WRITE(nvram_mtd, offset + magic_offset, sizeof(header->magic), 
									&magic_len, (char *)&header->magic);
	if (ret || magic_len != sizeof(header->magic)) {
		printk("nvram_commit: write MAGIC error\n");
		ret = -EIO;
		goto done;
	}

	/*
	 * Reading a few bytes back here will put the device
	 * back to the correct mode on certain flashes */
	offset = nvram_mtd->size - erasesize;
	ret = MTD_READ(nvram_mtd, offset, 4, &len, buf);

 done:
	up(&nvram_sem);
	kfree(buf);

	return ret;
}
Exemplo n.º 14
0
int
nvram_set(const char *name, const char *value)
{
	unsigned long flags;
	int ret;
	struct nvram_header *header;
#if WPS
	char wps_name[32];
	int wep_len;
#endif

	spin_lock_irqsave(&nvram_lock, flags);

	//printk("nvram_set: name = %s, value = %s!\n", name, value);
#ifdef CFE_UPDATE
		// write back to default sector as well, Chen-I
        if(strncmp(name, CFE_NVRAM_PREFIX, strlen(CFE_NVRAM_PREFIX))==0)
        {
                if(strcmp(name, CFE_NVRAM_COMMIT)==0)
                        cfe_commit();
                else if(strcmp(name, "asuscfe_dump") == 0)
                        ret = cfe_dump();
                else if(strcmp(name, CFE_NVRAM_WATCHDOG)==0)
                {
                        bcm947xx_watchdog_disable();
                }
                else
                {
                        cfe_update(name+strlen(CFE_NVRAM_PREFIX), value);
                        _nvram_set(name+strlen(CFE_NVRAM_PREFIX), value);
                }
        }
        else
#endif /* CFE_UPDATE */

#if WPS
	if (strncmp(name, "wlx_", 4) == 0) {
		memset(wps_name, 0, sizeof(wps_name));
		sprintf(wps_name, "wl0_%s", name+4);
		ret = _nvram_set(wps_name, value);
		spin_unlock_irqrestore(&nvram_lock, flags);
                return ret;
	}

	if (strncmp(name, "wl0_", 4) == 0) 
	{
		/* Authentication mode */
		if (strncmp(name, "wl0_akm", 7) == 0) {
			if (strncmp(value, "psk2", 4) == 0) { 		// WPA2-Personal
        	                _nvram_set("wl_auth_mode", "psk");
	                        _nvram_set("wl_wpa_mode", "2");
			}
		        else if (strncmp(value, "psk ", 4) == 0) { 	// WPA-Auto-Personal
        	                _nvram_set("wl_auth_mode", "psk");
                	        _nvram_set("wl_wpa_mode", "0");
	                }
                	else if (strncmp(value, "psk", 3) == 0) { 	// WPA-Personal
        	                _nvram_set("wl_auth_mode", "psk");
                	        _nvram_set("wl_wpa_mode", "1");
	                }
        	        else if (strncmp(value, "wpa2", 4) == 0) {	// WPA2-Enterprise
                	        _nvram_set("wl_auth_mode", "wpa2");
        	        }
		        else if (strncmp(value, "wpa ", 4) == 0) {	// WPA-Auto-Enterprise
	                       	_nvram_set("wl_wpa_mode", "4");
        	                _nvram_set("wl_auth_mode", "wpa");
                	}
                	else if (strncmp(value, "wpa", 3) == 0) {	// WPA-Enterprise
	                       	_nvram_set("wl_wpa_mode", "3");
        	                _nvram_set("wl_auth_mode", "wpa");
                	}
			_nvram_set("wl_akm", value);
		}
		/* WPS KEY*/
		else if (strcmp(name, "wl0_wpa_psk") == 0) {
			_nvram_set("wl_wpa_psk", value);
		}
		/* WEP type */
#if 1
		else if ((strncmp(name, "wl0_key", 7) == 0 )) {

			wep_len = strlen (value);
			memset(wps_name, 0, sizeof(wps_name));

			if ((wep_len == 5) || (wep_len == 10)) { /* wl0_key1~4*/
//				_nvram_set ("wl0_wep_x", "1");
				_nvram_set ("wl_wep_x", "1");
				sprintf(wps_name, "wl_%s", name+4);
			}
			else if ((wep_len == 13) || (wep_len == 26)) { 
//				_nvram_set ("wl0_wep_x", "2");
				_nvram_set ("wl_wep_x", "2");
				sprintf(wps_name, "wl_%s", name+4);
			}
			else { /* wl0_key index */
				sprintf(wps_name, "wl_%s", name+4);
			}
			_nvram_set(wps_name, value);
		}
#endif
		else if (strcmp(name, "wl0_ssid") == 0) {
	//		_nvram_set("wl0_ssid2", value);
	//		_nvram_set("wl_ssid2", value);
			_nvram_set("wl_ssid", value);
		}	
		else if (strcmp(name, "wl0_crypto") == 0) {
			_nvram_set("wl_crypto", value);
		}
		else if (strncmp(name, "wl0_wps", 7) == 0) {
			memset(wps_name, 0, sizeof(wps_name));
			sprintf(wps_name, "wl_%s", name+4);
			_nvram_set(wps_name, value);
		}

	}
	else if (strncmp(name, "wps_random_ssid_prefix", 22) == 0) {
		memset(wps_name, 0, sizeof(wps_name));
		sprintf(wps_name, "ASUS_");
		ret = _nvram_set("wps_random_ssid_prefix", wps_name);
		spin_unlock_irqrestore(&nvram_lock, flags);
		return ret;
	}

	if ((strcmp(name, "wl_wps_config_state") == 0) || (strcmp(name, "wl0_wps_config_state") == 0))
		_nvram_set("wps_config_state", value);
//	else if ((strncmp(name, "wps_proc_status", 15) == 0 ) && (strcmp(value, "4"))) /* WPS success*/
//		_nvram_set("wps_config_state", "1");

#if 0
	if(!strcmp(name, "wl0_ssid"))
		_nvram_set("wl_ssid", value);
	if(!strcmp(name, "wl0_ssid"))
		_nvram_set("wl_ssid", value);
        /* Set Wireless encryption */
        if (!strcmp(name, "wl0_akm")) {
		_nvram_set("wl_auth_mode", "psk");
                _nvram_set("wl_wpa_mode", "1");
	}
	else if (!strcmp("wl0_akm", "psk2")) {
                _nvram_set("wl_auth_mode", "psk");
                _nvram_set("wl_wpa_mode", "2");
        }
        else if (nvram_match("wl0_akm", "wpa")) {
                _nvram_set("wl_auth_mode", "wpa");
                _nvram_set("wl_wpa_mode", "3");
        }
        else if (nvram_match("wl0_akm", "wpa2")) {
                _nvram_set("wl_auth_mode", "wpa2");
        }
        else
                _nvram_set("wl_auth_mode", nvram_get("wl0_auth_mode"));
#endif
#endif /* WPS */

	if ((ret = _nvram_set(name, value))) {
		/* Consolidate space and try again */
		if ((header = kmalloc(NVRAM_SPACE, GFP_ATOMIC))) {
			if (_nvram_commit(header) == 0)
				ret = _nvram_set(name, value);
			kfree(header);
		}
	}
	spin_unlock_irqrestore(&nvram_lock, flags);

	return ret;
}