/*
* Filename: config.c
*
*
* Authors: Joshua Morris <josh.h.morris@us.ibm.com>
*	Philip Kelleher <pjk1939@linux.vnet.ibm.com>
*
* (C) Copyright 2013 IBM Corporation
*
* 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
*/

#include <linux/types.h>
#include <linux/crc32.h>
#include <linux/swab.h>

#include "rsxx_priv.h"
#include "rsxx_cfg.h"

static void initialize_config(struct rsxx_card_cfg *cfg)
{
	cfg->hdr.version = RSXX_CFG_VERSION;

	cfg->data.block_size        = RSXX_HW_BLK_SIZE;
	cfg->data.stripe_size       = RSXX_HW_BLK_SIZE;
	cfg->data.vendor_id         = RSXX_VENDOR_ID_IBM;
	cfg->data.cache_order       = (-1);
	cfg->data.intr_coal.mode    = RSXX_INTR_COAL_DISABLED;
	cfg->data.intr_coal.count   = 0;
	cfg->data.intr_coal.latency = 0;
}

static u32 config_data_crc32(struct rsxx_card_cfg *cfg)
{
	/*
	 * Return the compliment of the CRC to ensure compatibility
	 * (i.e. this is how early rsxx drivers did it.)
	 */

	return ~crc32(~0, &cfg->data, sizeof(cfg->data));
}


/*----------------- Config Byte Swap Functions -------------------*/
static void config_hdr_be_to_cpu(struct card_cfg_hdr *hdr)
{
	hdr->version = be32_to_cpu((__force __be32) hdr->version);
	hdr->crc     = be32_to_cpu((__force __be32) hdr->crc);
}

static void config_hdr_cpu_to_be(struct card_cfg_hdr *hdr)
{
	hdr->version = (__force u32) cpu_to_be32(hdr->version);
	hdr->crc     = (__force u32) cpu_to_be32(hdr->crc);
}

static void config_data_swab(struct rsxx_card_cfg *cfg)
{
	u32 *data = (u32 *) &cfg->data;
	int i;

	for (i = 0; i < (sizeof(cfg->data) / 4); i++)
		data[i] = swab32(data[i]);
}

static void config_data_le_to_cpu(struct rsxx_card_cfg *cfg)
{
	u32 *data = (u32 *) &cfg->data;
	int i;

	for (i = 0; i < (sizeof(cfg->data) / 4); i++)
		data[i] = le32_to_cpu((__force __le32) data[i]);
}

static void config_data_cpu_to_le(struct rsxx_card_cfg *cfg)
{
	u32 *data = (u32 *) &cfg->data;
	int i;

	for (i = 0; i < (sizeof(cfg->data) / 4); i++)
		data[i] = (__force u32) cpu_to_le32(data[i]);
}


/*----------------- Config Operations ------------------*/
static int rsxx_save_config(struct rsxx_cardinfo *card)
{
	struct rsxx_card_cfg cfg;
	int st;

	memcpy(&cfg, &card->config, sizeof(cfg));

	if (unlikely(cfg.hdr.version != RSXX_CFG_VERSION)) {
		dev_err(CARD_TO_DEV(card),
			"Cannot save config with invalid version %d\n",
			cfg.hdr.version);
		return -EINVAL;
	}

	/* Convert data to little endian for the CRC calculation. */
	config_data_cpu_to_le(&cfg);

	cfg.hdr.crc = config_data_crc32(&cfg);

	/*
	 * Swap the data from little endian to big endian so it can be
	 * stored.
	 */
	config_data_swab(&cfg);
	config_hdr_cpu_to_be(&cfg.hdr);

	st = rsxx_creg_write(card, CREG_ADD_CONFIG, sizeof(cfg), &cfg, 1);
	if (st)
		return st;

	return 0;
}

int rsxx_load_config(struct rsxx_cardinfo *card)
{
	int st;
	u32 crc;

	st = rsxx_creg_read(card, CREG_ADD_CONFIG, sizeof(card->config),
				&card->config, 1);
	if (st) {
		dev_err(CARD_TO_DEV(card),
			"Failed reading card config.\n");
		return st;
	}

	config_hdr_be_to_cpu(&card->config.hdr);

	if (card->config.hdr.version == RSXX_CFG_VERSION) {
		/*
		 * We calculate the CRC with the data in little endian, because
		 * early drivers did not take big endian CPUs into account.
		 * The data is always stored in big endian, so we need to byte
		 * swap it before calculating the CRC.
		 */

		config_data_swab(&card->config);

		/* Check the CRC */
		crc = config_data_crc32(&card->config);
		if (crc != card->config.hdr.crc) {
			dev_err(CARD_TO_DEV(card),
				"Config corruption detected!\n");
			dev_info(CARD_TO_DEV(card),
				"CRC (sb x%08x is x%08x)\n",
				card->config.hdr.crc, crc);
			return -EIO;
		}

		/* Convert the data to CPU byteorder */
		config_data_le_to_cpu(&card->config);

	} else if (card->config.hdr.version != 0) {
		dev_err(CARD_TO_DEV(card),
			"Invalid config version %d.\n",
			card->config.hdr.version);
		/*
		 * Config version changes require special handling from the
		 * user
		 */
		return -EINVAL;
	} else {
		dev_info(CARD_TO_DEV(card),
			"Initializing card configuration.\n");
		initialize_config(&card->config);
		st = rsxx_save_config(card);
		if (st)
			return st;
	}

	card->config_valid = 1;

	dev_dbg(CARD_TO_DEV(card), "version:     x%08x\n",
		card->config.hdr.version);
	dev_dbg(CARD_TO_DEV(card), "crc:         x%08x\n",
		card->config.hdr.crc);
	dev_dbg(CARD_TO_DEV(card), "block_size:  x%08x\n",
		card->config.data.block_size);
	dev_dbg(CARD_TO_DEV(card), "stripe_size: x%08x\n",
		card->config.data.stripe_size);
	dev_dbg(CARD_TO_DEV(card), "vendor_id:   x%08x\n",
		card->config.data.vendor_id);
	dev_dbg(CARD_TO_DEV(card), "cache_order: x%08x\n",
		card->config.data.cache_order);
	dev_dbg(CARD_TO_DEV(card), "mode:        x%08x\n",
		card->config.data.intr_coal.mode);
	dev_dbg(CARD_TO_DEV(card), "count:       x%08x\n",
		card->config.data.intr_coal.count);
	dev_dbg(CARD_TO_DEV(card), "latency:     x%08x\n",
		 card->config.data.intr_coal.latency);

	return 0;
}

