aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/sfc/mcdi.c
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2012-11-27 23:38:14 -0500
committerBen Hutchings <bhutchings@solarflare.com>2013-08-27 17:25:21 -0400
commit45a3fd55acc8989ff93d469e57b123cd3702a948 (patch)
tree39c1d3c5fdd95182b6832b2b7e27b765f4f97575 /drivers/net/ethernet/sfc/mcdi.c
parent141d748e70a22629ef1e1823f88b3d5741ac38af (diff)
sfc: Move MTD operations into efx_nic_type
Merge the per-NIC-type MTD probe selection and struct efx_mtd_ops into struct efx_nic_type. Move the implementations into the appropriate source files. Several NVRAM functions are now only called from MTD operations which are now implemented in the same file (falcon.c or mcdi.c). There is no need for them to be extern, or to be defined at all if CONFIG_SFC_MTD is not enabled, so move them into the #ifdef CONFIG_SFC_MTD sections in those files. Most of the SPI-related definitions are also only used in falcon.c, so move them there. Put the remainder of spi.h into nic.h (which previously included it). Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/ethernet/sfc/mcdi.c')
-rw-r--r--drivers/net/ethernet/sfc/mcdi.c352
1 files changed, 233 insertions, 119 deletions
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c
index 1c8bf81bdc03..67b07de2c599 100644
--- a/drivers/net/ethernet/sfc/mcdi.c
+++ b/drivers/net/ethernet/sfc/mcdi.c
@@ -811,125 +811,6 @@ fail:
811 return rc; 811 return rc;
812} 812}
813 813
814int efx_mcdi_nvram_update_start(struct efx_nic *efx, unsigned int type)
815{
816 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_UPDATE_START_IN_LEN);
817 int rc;
818
819 MCDI_SET_DWORD(inbuf, NVRAM_UPDATE_START_IN_TYPE, type);
820
821 BUILD_BUG_ON(MC_CMD_NVRAM_UPDATE_START_OUT_LEN != 0);
822
823 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_UPDATE_START, inbuf, sizeof(inbuf),
824 NULL, 0, NULL);
825 if (rc)
826 goto fail;
827
828 return 0;
829
830fail:
831 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
832 return rc;
833}
834
835int efx_mcdi_nvram_read(struct efx_nic *efx, unsigned int type,
836 loff_t offset, u8 *buffer, size_t length)
837{
838 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_READ_IN_LEN);
839 MCDI_DECLARE_BUF(outbuf,
840 MC_CMD_NVRAM_READ_OUT_LEN(EFX_MCDI_NVRAM_LEN_MAX));
841 size_t outlen;
842 int rc;
843
844 MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_TYPE, type);
845 MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_OFFSET, offset);
846 MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_LENGTH, length);
847
848 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_READ, inbuf, sizeof(inbuf),
849 outbuf, sizeof(outbuf), &outlen);
850 if (rc)
851 goto fail;
852
853 memcpy(buffer, MCDI_PTR(outbuf, NVRAM_READ_OUT_READ_BUFFER), length);
854 return 0;
855
856fail:
857 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
858 return rc;
859}
860
861int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type,
862 loff_t offset, const u8 *buffer, size_t length)
863{
864 MCDI_DECLARE_BUF(inbuf,
865 MC_CMD_NVRAM_WRITE_IN_LEN(EFX_MCDI_NVRAM_LEN_MAX));
866 int rc;
867
868 MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_TYPE, type);
869 MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_OFFSET, offset);
870 MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_LENGTH, length);
871 memcpy(MCDI_PTR(inbuf, NVRAM_WRITE_IN_WRITE_BUFFER), buffer, length);
872
873 BUILD_BUG_ON(MC_CMD_NVRAM_WRITE_OUT_LEN != 0);
874
875 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_WRITE, inbuf,
876 ALIGN(MC_CMD_NVRAM_WRITE_IN_LEN(length), 4),
877 NULL, 0, NULL);
878 if (rc)
879 goto fail;
880
881 return 0;
882
883fail:
884 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
885 return rc;
886}
887
888int efx_mcdi_nvram_erase(struct efx_nic *efx, unsigned int type,
889 loff_t offset, size_t length)
890{
891 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_ERASE_IN_LEN);
892 int rc;
893
894 MCDI_SET_DWORD(inbuf, NVRAM_ERASE_IN_TYPE, type);
895 MCDI_SET_DWORD(inbuf, NVRAM_ERASE_IN_OFFSET, offset);
896 MCDI_SET_DWORD(inbuf, NVRAM_ERASE_IN_LENGTH, length);
897
898 BUILD_BUG_ON(MC_CMD_NVRAM_ERASE_OUT_LEN != 0);
899
900 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_ERASE, inbuf, sizeof(inbuf),
901 NULL, 0, NULL);
902 if (rc)
903 goto fail;
904
905 return 0;
906
907fail:
908 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
909 return rc;
910}
911
912int efx_mcdi_nvram_update_finish(struct efx_nic *efx, unsigned int type)
913{
914 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN);
915 int rc;
916
917 MCDI_SET_DWORD(inbuf, NVRAM_UPDATE_FINISH_IN_TYPE, type);
918
919 BUILD_BUG_ON(MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN != 0);
920
921 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_UPDATE_FINISH, inbuf, sizeof(inbuf),
922 NULL, 0, NULL);
923 if (rc)
924 goto fail;
925
926 return 0;
927
928fail:
929 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
930 return rc;
931}
932
933static int efx_mcdi_nvram_test(struct efx_nic *efx, unsigned int type) 814static int efx_mcdi_nvram_test(struct efx_nic *efx, unsigned int type)
934{ 815{
935 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_TEST_IN_LEN); 816 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_TEST_IN_LEN);
@@ -1272,3 +1153,236 @@ fail:
1272 return rc; 1153 return rc;
1273} 1154}
1274 1155
1156#ifdef CONFIG_SFC_MTD
1157
1158#define EFX_MCDI_NVRAM_LEN_MAX 128
1159
1160static int efx_mcdi_nvram_update_start(struct efx_nic *efx, unsigned int type)
1161{
1162 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_UPDATE_START_IN_LEN);
1163 int rc;
1164
1165 MCDI_SET_DWORD(inbuf, NVRAM_UPDATE_START_IN_TYPE, type);
1166
1167 BUILD_BUG_ON(MC_CMD_NVRAM_UPDATE_START_OUT_LEN != 0);
1168
1169 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_UPDATE_START, inbuf, sizeof(inbuf),
1170 NULL, 0, NULL);
1171 if (rc)
1172 goto fail;
1173
1174 return 0;
1175
1176fail:
1177 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
1178 return rc;
1179}
1180
1181static int efx_mcdi_nvram_read(struct efx_nic *efx, unsigned int type,
1182 loff_t offset, u8 *buffer, size_t length)
1183{
1184 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_READ_IN_LEN);
1185 MCDI_DECLARE_BUF(outbuf,
1186 MC_CMD_NVRAM_READ_OUT_LEN(EFX_MCDI_NVRAM_LEN_MAX));
1187 size_t outlen;
1188 int rc;
1189
1190 MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_TYPE, type);
1191 MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_OFFSET, offset);
1192 MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_LENGTH, length);
1193
1194 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_READ, inbuf, sizeof(inbuf),
1195 outbuf, sizeof(outbuf), &outlen);
1196 if (rc)
1197 goto fail;
1198
1199 memcpy(buffer, MCDI_PTR(outbuf, NVRAM_READ_OUT_READ_BUFFER), length);
1200 return 0;
1201
1202fail:
1203 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
1204 return rc;
1205}
1206
1207static int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type,
1208 loff_t offset, const u8 *buffer, size_t length)
1209{
1210 MCDI_DECLARE_BUF(inbuf,
1211 MC_CMD_NVRAM_WRITE_IN_LEN(EFX_MCDI_NVRAM_LEN_MAX));
1212 int rc;
1213
1214 MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_TYPE, type);
1215 MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_OFFSET, offset);
1216 MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_LENGTH, length);
1217 memcpy(MCDI_PTR(inbuf, NVRAM_WRITE_IN_WRITE_BUFFER), buffer, length);
1218
1219 BUILD_BUG_ON(MC_CMD_NVRAM_WRITE_OUT_LEN != 0);
1220
1221 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_WRITE, inbuf,
1222 ALIGN(MC_CMD_NVRAM_WRITE_IN_LEN(length), 4),
1223 NULL, 0, NULL);
1224 if (rc)
1225 goto fail;
1226
1227 return 0;
1228
1229fail:
1230 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
1231 return rc;
1232}
1233
1234static int efx_mcdi_nvram_erase(struct efx_nic *efx, unsigned int type,
1235 loff_t offset, size_t length)
1236{
1237 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_ERASE_IN_LEN);
1238 int rc;
1239
1240 MCDI_SET_DWORD(inbuf, NVRAM_ERASE_IN_TYPE, type);
1241 MCDI_SET_DWORD(inbuf, NVRAM_ERASE_IN_OFFSET, offset);
1242 MCDI_SET_DWORD(inbuf, NVRAM_ERASE_IN_LENGTH, length);
1243
1244 BUILD_BUG_ON(MC_CMD_NVRAM_ERASE_OUT_LEN != 0);
1245
1246 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_ERASE, inbuf, sizeof(inbuf),
1247 NULL, 0, NULL);
1248 if (rc)
1249 goto fail;
1250
1251 return 0;
1252
1253fail:
1254 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
1255 return rc;
1256}
1257
1258static int efx_mcdi_nvram_update_finish(struct efx_nic *efx, unsigned int type)
1259{
1260 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN);
1261 int rc;
1262
1263 MCDI_SET_DWORD(inbuf, NVRAM_UPDATE_FINISH_IN_TYPE, type);
1264
1265 BUILD_BUG_ON(MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN != 0);
1266
1267 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_UPDATE_FINISH, inbuf, sizeof(inbuf),
1268 NULL, 0, NULL);
1269 if (rc)
1270 goto fail;
1271
1272 return 0;
1273
1274fail:
1275 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
1276 return rc;
1277}
1278
1279int efx_mcdi_mtd_read(struct mtd_info *mtd, loff_t start,
1280 size_t len, size_t *retlen, u8 *buffer)
1281{
1282 struct efx_mcdi_mtd_partition *part = to_efx_mcdi_mtd_partition(mtd);
1283 struct efx_nic *efx = mtd->priv;
1284 loff_t offset = start;
1285 loff_t end = min_t(loff_t, start + len, mtd->size);
1286 size_t chunk;
1287 int rc = 0;
1288
1289 while (offset < end) {
1290 chunk = min_t(size_t, end - offset, EFX_MCDI_NVRAM_LEN_MAX);
1291 rc = efx_mcdi_nvram_read(efx, part->nvram_type, offset,
1292 buffer, chunk);
1293 if (rc)
1294 goto out;
1295 offset += chunk;
1296 buffer += chunk;
1297 }
1298out:
1299 *retlen = offset - start;
1300 return rc;
1301}
1302
1303int efx_mcdi_mtd_erase(struct mtd_info *mtd, loff_t start, size_t len)
1304{
1305 struct efx_mcdi_mtd_partition *part = to_efx_mcdi_mtd_partition(mtd);
1306 struct efx_nic *efx = mtd->priv;
1307 loff_t offset = start & ~((loff_t)(mtd->erasesize - 1));
1308 loff_t end = min_t(loff_t, start + len, mtd->size);
1309 size_t chunk = part->common.mtd.erasesize;
1310 int rc = 0;
1311
1312 if (!part->updating) {
1313 rc = efx_mcdi_nvram_update_start(efx, part->nvram_type);
1314 if (rc)
1315 goto out;
1316 part->updating = true;
1317 }
1318
1319 /* The MCDI interface can in fact do multiple erase blocks at once;
1320 * but erasing may be slow, so we make multiple calls here to avoid
1321 * tripping the MCDI RPC timeout. */
1322 while (offset < end) {
1323 rc = efx_mcdi_nvram_erase(efx, part->nvram_type, offset,
1324 chunk);
1325 if (rc)
1326 goto out;
1327 offset += chunk;
1328 }
1329out:
1330 return rc;
1331}
1332
1333int efx_mcdi_mtd_write(struct mtd_info *mtd, loff_t start,
1334 size_t len, size_t *retlen, const u8 *buffer)
1335{
1336 struct efx_mcdi_mtd_partition *part = to_efx_mcdi_mtd_partition(mtd);
1337 struct efx_nic *efx = mtd->priv;
1338 loff_t offset = start;
1339 loff_t end = min_t(loff_t, start + len, mtd->size);
1340 size_t chunk;
1341 int rc = 0;
1342
1343 if (!part->updating) {
1344 rc = efx_mcdi_nvram_update_start(efx, part->nvram_type);
1345 if (rc)
1346 goto out;
1347 part->updating = true;
1348 }
1349
1350 while (offset < end) {
1351 chunk = min_t(size_t, end - offset, EFX_MCDI_NVRAM_LEN_MAX);
1352 rc = efx_mcdi_nvram_write(efx, part->nvram_type, offset,
1353 buffer, chunk);
1354 if (rc)
1355 goto out;
1356 offset += chunk;
1357 buffer += chunk;
1358 }
1359out:
1360 *retlen = offset - start;
1361 return rc;
1362}
1363
1364int efx_mcdi_mtd_sync(struct mtd_info *mtd)
1365{
1366 struct efx_mcdi_mtd_partition *part = to_efx_mcdi_mtd_partition(mtd);
1367 struct efx_nic *efx = mtd->priv;
1368 int rc = 0;
1369
1370 if (part->updating) {
1371 part->updating = false;
1372 rc = efx_mcdi_nvram_update_finish(efx, part->nvram_type);
1373 }
1374
1375 return rc;
1376}
1377
1378void efx_mcdi_mtd_rename(struct efx_mtd_partition *part)
1379{
1380 struct efx_mcdi_mtd_partition *mcdi_part =
1381 container_of(part, struct efx_mcdi_mtd_partition, common);
1382 struct efx_nic *efx = part->mtd.priv;
1383
1384 snprintf(part->name, sizeof(part->name), "%s %s:%02x",
1385 efx->name, part->type_name, mcdi_part->fw_subtype);
1386}
1387
1388#endif /* CONFIG_SFC_MTD */