| /* |
| * Copyright (C) 2017 Amlogic, Inc. All rights reserved. |
| * * |
| This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * * |
| This program is distributed in the hope that 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. |
| * * |
| Description: |
| */ |
| |
| #include "../include/phynand.h" |
| |
| |
| static struct amlnand_chip *aml_chip_key = NULL; |
| static struct amlnand_chip *aml_ddr_para = NULL; |
| |
| /* |
| * This funcion reads the u-boot keys. |
| */ |
| int amlnf_key_read(u8 * buf, int len, uint32_t *actual_lenth) |
| { |
| struct amlnand_chip * aml_chip = aml_chip_key; |
| struct nand_menson_key *key_ptr = NULL; |
| u32 keysize = aml_chip->keysize; |
| int error = 0; |
| |
| *actual_lenth = keysize; |
| |
| if (aml_chip == NULL) { |
| printk("%s(): amlnf key not ready yet!", __func__); |
| return -EFAULT; |
| } |
| |
| if (len > keysize) { |
| /* |
| No return here! keep consistent, should memset zero |
| for the rest. |
| */ |
| printk("%s key data len too much\n",__func__); |
| memset(buf + keysize, 0 , len - keysize); |
| //return -EFAULT; |
| } |
| |
| key_ptr = kzalloc(aml_chip->keysize + sizeof(u32), GFP_KERNEL); |
| if (key_ptr == NULL) |
| return -ENOMEM; |
| |
| error = amlnand_read_info_by_name(aml_chip, |
| (u8 *)&(aml_chip->nand_key), |
| (u8 *)key_ptr, |
| (u8*)KEY_INFO_HEAD_MAGIC, |
| aml_chip->keysize); |
| if (error) { |
| printk("%s: read key error\n",__func__); |
| error = -EFAULT; |
| goto exit; |
| } |
| |
| memcpy(buf, key_ptr->data, keysize); |
| |
| exit: |
| kfree(key_ptr); |
| return 0; |
| } |
| |
| /* |
| * This funcion write the keys. |
| */ |
| int amlnf_key_write(u8 *buf, int len, uint32_t *actual_lenth) |
| { |
| struct amlnand_chip * aml_chip = aml_chip_key; |
| struct nand_menson_key *key_ptr = NULL; |
| u32 keysize = aml_chip->keysize; |
| int error = 0; |
| struct nand_flash *flash = &aml_chip_key->flash; |
| |
| if (aml_chip == NULL) { |
| printk("%s(): amlnf key not ready yet!", __func__); |
| return -EFAULT; |
| } |
| |
| if (len > keysize) { |
| /* |
| No return here! keep consistent, should memset zero |
| for the rest. |
| */ |
| printk("key data len too much,%s\n",__func__); |
| memset(buf + keysize, 0 , len - keysize); |
| //return -EFAULT; |
| } |
| |
| key_ptr = kzalloc(aml_chip->keysize + flash->pagesize, GFP_KERNEL); |
| if (key_ptr == NULL) |
| return -ENOMEM; |
| |
| memcpy(key_ptr->data, buf, keysize); |
| |
| error = amlnand_save_info_by_name(aml_chip, |
| (u8 *)&(aml_chip->nand_key), |
| (u8 *)key_ptr, |
| (u8 *)KEY_INFO_HEAD_MAGIC, |
| aml_chip->keysize); |
| if (error) { |
| printk("save key error,%s\n",__func__); |
| error = -EFAULT; |
| goto exit; |
| } |
| exit: |
| kfree(key_ptr); |
| return error; |
| } |
| |
| int amlnf_key_erase(void) |
| { |
| int ret = 0; |
| if (aml_chip_key == NULL) { |
| printk("%s amlnf not ready yet!\n", __func__); |
| return -1; |
| } |
| ret = amlnand_erase_info_by_name(aml_chip_key, |
| (u8 *)&(aml_chip_key->nand_key), |
| (u8 *)KEY_INFO_HEAD_MAGIC); |
| if (ret) { |
| printk("%s erase key error\n", __func__); |
| ret = -EFAULT; |
| } |
| return ret; |
| } |
| |
| |
| int aml_key_init(struct amlnand_chip *aml_chip) |
| { |
| int ret = 0; |
| struct nand_menson_key *key_ptr = NULL; |
| |
| /* avoid null */ |
| aml_chip_key = aml_chip; |
| |
| key_ptr = aml_nand_malloc(aml_chip->keysize +sizeof(u32)); |
| if (key_ptr == NULL) { |
| printk("nand malloc for key_ptr failed"); |
| ret = -1; |
| goto exit_error0; |
| } |
| memset(key_ptr, 0x0, aml_chip->keysize + sizeof(u32)); |
| printk("%s probe.\n", __func__); |
| |
| ret = amlnand_info_init(aml_chip, |
| (u8 *)&(aml_chip->nand_key), |
| (u8 *)key_ptr,(u8 *)KEY_INFO_HEAD_MAGIC, |
| aml_chip->keysize); |
| if (ret < 0) { |
| printk("invalid nand key\n"); |
| } |
| exit_error0: |
| if (key_ptr) { |
| aml_nand_free(key_ptr); |
| key_ptr =NULL; |
| } |
| return ret; |
| } |
| |
| int amlnf_ddr_parameter_read(u8 * buf, int len) |
| { |
| struct amlnand_chip * aml_chip = aml_ddr_para; |
| u8 *ddr_ptr = NULL; |
| int ddrsize = (int)aml_chip->ddrsize; |
| int error = 0; |
| |
| if (aml_chip == NULL) { |
| printk("%s(): amlnf ddr parameter not ready yet!", __func__); |
| return -EFAULT; |
| } |
| |
| if (len > ddrsize) { |
| /* |
| No return here! keep consistent, should memset zero |
| for the rest. |
| */ |
| printk("%s ddr data len too much\n",__func__); |
| memset(buf + ddrsize, 0 , len - ddrsize); /*need fixme liuxj*/ |
| //return -EFAULT; |
| } |
| |
| ddr_ptr = kzalloc(aml_chip->ddrsize, GFP_KERNEL); |
| if (ddr_ptr == NULL) |
| return -ENOMEM; |
| |
| error = amlnand_read_info_by_name(aml_chip, |
| (u8 *)&(aml_chip->nand_ddr_para), |
| (u8 *)ddr_ptr, |
| (u8 *)DDR_PARAMETER_HEAD_MAGIC, |
| aml_chip->ddrsize); |
| if (error) { |
| printk("%s: read ddr para error\n",__func__); |
| error = -EFAULT; |
| goto exit; |
| } |
| |
| ddrsize = min_t(int, len, ddrsize); |
| memcpy(buf, ddr_ptr, ddrsize); |
| exit: |
| kfree(ddr_ptr); |
| return 0; |
| } |
| |
| |
| int amlnf_ddr_parameter_write(u8 *buf, int len) |
| { |
| struct amlnand_chip * aml_chip = aml_ddr_para; |
| u8 *ddr_ptr = NULL; |
| int ddrsize = (int)aml_chip->ddrsize; |
| int error = 0; |
| |
| if (aml_chip == NULL) { |
| printk("%s(): amlnf ddr parameter not ready yet!", __func__); |
| return -EFAULT; |
| } |
| |
| if (len > ddrsize) { |
| /* |
| No return here! keep consistent, should memset zero |
| for the rest. |
| */ |
| printk("ddr parameter data len too much,%s\n",__func__); |
| memset(buf + ddrsize, 0 , len - ddrsize); |
| //return -EFAULT; |
| } |
| |
| ddr_ptr = kzalloc(ddrsize, GFP_KERNEL); |
| if (ddr_ptr == NULL) |
| return -ENOMEM; |
| |
| ddrsize = min_t(int, len, ddrsize); |
| memcpy(ddr_ptr, buf, ddrsize); |
| |
| error = amlnand_save_info_by_name(aml_chip, |
| (u8 *)&(aml_chip->nand_ddr_para), |
| (u8 *)ddr_ptr, |
| (u8 *)DDR_PARAMETER_HEAD_MAGIC, |
| aml_chip->ddrsize); |
| if (error) { |
| printk("save ddr parameter error,%s\n",__func__); |
| error = -EFAULT; |
| goto exit; |
| } |
| exit: |
| kfree(ddr_ptr); |
| return error; |
| } |
| |
| int amlnf_ddr_parameter_erase(void) |
| { |
| int ret = 0; |
| if (aml_ddr_para == NULL) { |
| printk("%s amlnf not ready yet!\n", __func__); |
| return -1; |
| } |
| ret = amlnand_erase_info_by_name(aml_ddr_para, |
| (u8 *)&(aml_ddr_para->nand_ddr_para), |
| (u8 *)DDR_PARAMETER_HEAD_MAGIC); |
| if (ret) { |
| printk("%s erase ddr error\n", __func__); |
| ret = -EFAULT; |
| } |
| return ret; |
| } |
| |
| |
| int aml_ddr_parameter_init(struct amlnand_chip *aml_chip) |
| { |
| int ret = 0; |
| u8 *ddr_ptr = NULL; |
| |
| /* avoid null */ |
| aml_ddr_para = aml_chip; |
| |
| ddr_ptr = aml_nand_malloc(aml_chip->ddrsize); |
| if (ddr_ptr == NULL) { |
| printk("nand malloc for ddr failed"); |
| ret = -1; |
| goto exit_error0; |
| } |
| memset(ddr_ptr, 0x0, aml_chip->ddrsize); |
| printk("%s probe.\n", __func__); |
| |
| ret = amlnand_info_init(aml_chip, |
| (u8 *)&(aml_chip->nand_ddr_para), |
| (u8 *)ddr_ptr,(u8 *)DDR_PARAMETER_HEAD_MAGIC, |
| aml_chip->ddrsize); |
| if (ret < 0) { |
| printk("invalid nand ddr parameter\n"); |
| } |
| exit_error0: |
| if (ddr_ptr) { |
| aml_nand_free(ddr_ptr); |
| ddr_ptr =NULL; |
| } |
| return ret; |
| } |
| |