1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Authors: Joshua Morris <josh.h.morris@us.ibm.com>
6 * Philip Kelleher <pjk1939@linux.vnet.ibm.com>
8 * (C) Copyright 2013 IBM Corporation
11 #include <linux/types.h>
12 #include <linux/crc32.h>
13 #include <linux/swab.h>
15 #include "rsxx_priv.h"
18 static void initialize_config(struct rsxx_card_cfg
*cfg
)
20 cfg
->hdr
.version
= RSXX_CFG_VERSION
;
22 cfg
->data
.block_size
= RSXX_HW_BLK_SIZE
;
23 cfg
->data
.stripe_size
= RSXX_HW_BLK_SIZE
;
24 cfg
->data
.vendor_id
= RSXX_VENDOR_ID_IBM
;
25 cfg
->data
.cache_order
= (-1);
26 cfg
->data
.intr_coal
.mode
= RSXX_INTR_COAL_DISABLED
;
27 cfg
->data
.intr_coal
.count
= 0;
28 cfg
->data
.intr_coal
.latency
= 0;
31 static u32
config_data_crc32(struct rsxx_card_cfg
*cfg
)
34 * Return the compliment of the CRC to ensure compatibility
35 * (i.e. this is how early rsxx drivers did it.)
38 return ~crc32(~0, &cfg
->data
, sizeof(cfg
->data
));
42 /*----------------- Config Byte Swap Functions -------------------*/
43 static void config_hdr_be_to_cpu(struct card_cfg_hdr
*hdr
)
45 hdr
->version
= be32_to_cpu((__force __be32
) hdr
->version
);
46 hdr
->crc
= be32_to_cpu((__force __be32
) hdr
->crc
);
49 static void config_hdr_cpu_to_be(struct card_cfg_hdr
*hdr
)
51 hdr
->version
= (__force u32
) cpu_to_be32(hdr
->version
);
52 hdr
->crc
= (__force u32
) cpu_to_be32(hdr
->crc
);
55 static void config_data_swab(struct rsxx_card_cfg
*cfg
)
57 u32
*data
= (u32
*) &cfg
->data
;
60 for (i
= 0; i
< (sizeof(cfg
->data
) / 4); i
++)
61 data
[i
] = swab32(data
[i
]);
64 static void config_data_le_to_cpu(struct rsxx_card_cfg
*cfg
)
66 u32
*data
= (u32
*) &cfg
->data
;
69 for (i
= 0; i
< (sizeof(cfg
->data
) / 4); i
++)
70 data
[i
] = le32_to_cpu((__force __le32
) data
[i
]);
73 static void config_data_cpu_to_le(struct rsxx_card_cfg
*cfg
)
75 u32
*data
= (u32
*) &cfg
->data
;
78 for (i
= 0; i
< (sizeof(cfg
->data
) / 4); i
++)
79 data
[i
] = (__force u32
) cpu_to_le32(data
[i
]);
83 /*----------------- Config Operations ------------------*/
84 static int rsxx_save_config(struct rsxx_cardinfo
*card
)
86 struct rsxx_card_cfg cfg
;
89 memcpy(&cfg
, &card
->config
, sizeof(cfg
));
91 if (unlikely(cfg
.hdr
.version
!= RSXX_CFG_VERSION
)) {
92 dev_err(CARD_TO_DEV(card
),
93 "Cannot save config with invalid version %d\n",
98 /* Convert data to little endian for the CRC calculation. */
99 config_data_cpu_to_le(&cfg
);
101 cfg
.hdr
.crc
= config_data_crc32(&cfg
);
104 * Swap the data from little endian to big endian so it can be
107 config_data_swab(&cfg
);
108 config_hdr_cpu_to_be(&cfg
.hdr
);
110 st
= rsxx_creg_write(card
, CREG_ADD_CONFIG
, sizeof(cfg
), &cfg
, 1);
117 int rsxx_load_config(struct rsxx_cardinfo
*card
)
122 st
= rsxx_creg_read(card
, CREG_ADD_CONFIG
, sizeof(card
->config
),
125 dev_err(CARD_TO_DEV(card
),
126 "Failed reading card config.\n");
130 config_hdr_be_to_cpu(&card
->config
.hdr
);
132 if (card
->config
.hdr
.version
== RSXX_CFG_VERSION
) {
134 * We calculate the CRC with the data in little endian, because
135 * early drivers did not take big endian CPUs into account.
136 * The data is always stored in big endian, so we need to byte
137 * swap it before calculating the CRC.
140 config_data_swab(&card
->config
);
143 crc
= config_data_crc32(&card
->config
);
144 if (crc
!= card
->config
.hdr
.crc
) {
145 dev_err(CARD_TO_DEV(card
),
146 "Config corruption detected!\n");
147 dev_info(CARD_TO_DEV(card
),
148 "CRC (sb x%08x is x%08x)\n",
149 card
->config
.hdr
.crc
, crc
);
153 /* Convert the data to CPU byteorder */
154 config_data_le_to_cpu(&card
->config
);
156 } else if (card
->config
.hdr
.version
!= 0) {
157 dev_err(CARD_TO_DEV(card
),
158 "Invalid config version %d.\n",
159 card
->config
.hdr
.version
);
161 * Config version changes require special handling from the
166 dev_info(CARD_TO_DEV(card
),
167 "Initializing card configuration.\n");
168 initialize_config(&card
->config
);
169 st
= rsxx_save_config(card
);
174 card
->config_valid
= 1;
176 dev_dbg(CARD_TO_DEV(card
), "version: x%08x\n",
177 card
->config
.hdr
.version
);
178 dev_dbg(CARD_TO_DEV(card
), "crc: x%08x\n",
179 card
->config
.hdr
.crc
);
180 dev_dbg(CARD_TO_DEV(card
), "block_size: x%08x\n",
181 card
->config
.data
.block_size
);
182 dev_dbg(CARD_TO_DEV(card
), "stripe_size: x%08x\n",
183 card
->config
.data
.stripe_size
);
184 dev_dbg(CARD_TO_DEV(card
), "vendor_id: x%08x\n",
185 card
->config
.data
.vendor_id
);
186 dev_dbg(CARD_TO_DEV(card
), "cache_order: x%08x\n",
187 card
->config
.data
.cache_order
);
188 dev_dbg(CARD_TO_DEV(card
), "mode: x%08x\n",
189 card
->config
.data
.intr_coal
.mode
);
190 dev_dbg(CARD_TO_DEV(card
), "count: x%08x\n",
191 card
->config
.data
.intr_coal
.count
);
192 dev_dbg(CARD_TO_DEV(card
), "latency: x%08x\n",
193 card
->config
.data
.intr_coal
.latency
);