aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c55
1 files changed, 32 insertions, 23 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index ad5002211ab4..6b874dab4120 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1284,7 +1284,7 @@ static void iwl_nic_start(struct iwl_priv *priv)
1284 */ 1284 */
1285static int iwl_read_ucode(struct iwl_priv *priv) 1285static int iwl_read_ucode(struct iwl_priv *priv)
1286{ 1286{
1287 struct iwl_ucode *ucode; 1287 struct iwl_ucode_header *ucode;
1288 int ret = -EINVAL, index; 1288 int ret = -EINVAL, index;
1289 const struct firmware *ucode_raw; 1289 const struct firmware *ucode_raw;
1290 const char *name_pre = priv->cfg->fw_name_pre; 1290 const char *name_pre = priv->cfg->fw_name_pre;
@@ -1293,7 +1293,8 @@ static int iwl_read_ucode(struct iwl_priv *priv)
1293 char buf[25]; 1293 char buf[25];
1294 u8 *src; 1294 u8 *src;
1295 size_t len; 1295 size_t len;
1296 u32 api_ver, inst_size, data_size, init_size, init_data_size, boot_size; 1296 u32 api_ver, build;
1297 u32 inst_size, data_size, init_size, init_data_size, boot_size;
1297 1298
1298 /* Ask kernel firmware_class module to get the boot firmware off disk. 1299 /* Ask kernel firmware_class module to get the boot firmware off disk.
1299 * request_firmware() is synchronous, file is in memory on return. */ 1300 * request_firmware() is synchronous, file is in memory on return. */
@@ -1323,23 +1324,26 @@ static int iwl_read_ucode(struct iwl_priv *priv)
1323 if (ret < 0) 1324 if (ret < 0)
1324 goto error; 1325 goto error;
1325 1326
1326 /* Make sure that we got at least our header! */ 1327 /* Make sure that we got at least the v1 header! */
1327 if (ucode_raw->size < sizeof(*ucode)) { 1328 if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) {
1328 IWL_ERR(priv, "File size way too small!\n"); 1329 IWL_ERR(priv, "File size way too small!\n");
1329 ret = -EINVAL; 1330 ret = -EINVAL;
1330 goto err_release; 1331 goto err_release;
1331 } 1332 }
1332 1333
1333 /* Data from ucode file: header followed by uCode images */ 1334 /* Data from ucode file: header followed by uCode images */
1334 ucode = (void *)ucode_raw->data; 1335 ucode = (struct iwl_ucode_header *)ucode_raw->data;
1335 1336
1336 priv->ucode_ver = le32_to_cpu(ucode->ver); 1337 priv->ucode_ver = le32_to_cpu(ucode->ver);
1337 api_ver = IWL_UCODE_API(priv->ucode_ver); 1338 api_ver = IWL_UCODE_API(priv->ucode_ver);
1338 inst_size = le32_to_cpu(ucode->inst_size); 1339 build = priv->cfg->ops->ucode->get_build(ucode, api_ver);
1339 data_size = le32_to_cpu(ucode->data_size); 1340 inst_size = priv->cfg->ops->ucode->get_inst_size(ucode, api_ver);
1340 init_size = le32_to_cpu(ucode->init_size); 1341 data_size = priv->cfg->ops->ucode->get_data_size(ucode, api_ver);
1341 init_data_size = le32_to_cpu(ucode->init_data_size); 1342 init_size = priv->cfg->ops->ucode->get_init_size(ucode, api_ver);
1342 boot_size = le32_to_cpu(ucode->boot_size); 1343 init_data_size =
1344 priv->cfg->ops->ucode->get_init_data_size(ucode, api_ver);
1345 boot_size = priv->cfg->ops->ucode->get_boot_size(ucode, api_ver);
1346 src = priv->cfg->ops->ucode->get_data(ucode, api_ver);
1343 1347
1344 /* api_ver should match the api version forming part of the 1348 /* api_ver should match the api version forming part of the
1345 * firmware filename ... but we don't check for that and only rely 1349 * firmware filename ... but we don't check for that and only rely
@@ -1365,6 +1369,9 @@ static int iwl_read_ucode(struct iwl_priv *priv)
1365 IWL_UCODE_API(priv->ucode_ver), 1369 IWL_UCODE_API(priv->ucode_ver),
1366 IWL_UCODE_SERIAL(priv->ucode_ver)); 1370 IWL_UCODE_SERIAL(priv->ucode_ver));
1367 1371
1372 if (build)
1373 IWL_DEBUG_INFO(priv, "Build %u\n", build);
1374
1368 IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n", 1375 IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
1369 priv->ucode_ver); 1376 priv->ucode_ver);
1370 IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n", 1377 IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
@@ -1379,12 +1386,14 @@ static int iwl_read_ucode(struct iwl_priv *priv)
1379 boot_size); 1386 boot_size);
1380 1387
1381 /* Verify size of file vs. image size info in file's header */ 1388 /* Verify size of file vs. image size info in file's header */
1382 if (ucode_raw->size < sizeof(*ucode) + 1389 if (ucode_raw->size !=
1390 priv->cfg->ops->ucode->get_header_size(api_ver) +
1383 inst_size + data_size + init_size + 1391 inst_size + data_size + init_size +
1384 init_data_size + boot_size) { 1392 init_data_size + boot_size) {
1385 1393
1386 IWL_DEBUG_INFO(priv, "uCode file size %d too small\n", 1394 IWL_DEBUG_INFO(priv,
1387 (int)ucode_raw->size); 1395 "uCode file size %d does not match expected size\n",
1396 (int)ucode_raw->size);
1388 ret = -EINVAL; 1397 ret = -EINVAL;
1389 goto err_release; 1398 goto err_release;
1390 } 1399 }
@@ -1464,42 +1473,42 @@ static int iwl_read_ucode(struct iwl_priv *priv)
1464 /* Copy images into buffers for card's bus-master reads ... */ 1473 /* Copy images into buffers for card's bus-master reads ... */
1465 1474
1466 /* Runtime instructions (first block of data in file) */ 1475 /* Runtime instructions (first block of data in file) */
1467 src = &ucode->data[0]; 1476 len = inst_size;
1468 len = priv->ucode_code.len;
1469 IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n", len); 1477 IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n", len);
1470 memcpy(priv->ucode_code.v_addr, src, len); 1478 memcpy(priv->ucode_code.v_addr, src, len);
1479 src += len;
1480
1471 IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n", 1481 IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
1472 priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr); 1482 priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
1473 1483
1474 /* Runtime data (2nd block) 1484 /* Runtime data (2nd block)
1475 * NOTE: Copy into backup buffer will be done in iwl_up() */ 1485 * NOTE: Copy into backup buffer will be done in iwl_up() */
1476 src = &ucode->data[inst_size]; 1486 len = data_size;
1477 len = priv->ucode_data.len;
1478 IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", len); 1487 IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", len);
1479 memcpy(priv->ucode_data.v_addr, src, len); 1488 memcpy(priv->ucode_data.v_addr, src, len);
1480 memcpy(priv->ucode_data_backup.v_addr, src, len); 1489 memcpy(priv->ucode_data_backup.v_addr, src, len);
1490 src += len;
1481 1491
1482 /* Initialization instructions (3rd block) */ 1492 /* Initialization instructions (3rd block) */
1483 if (init_size) { 1493 if (init_size) {
1484 src = &ucode->data[inst_size + data_size]; 1494 len = init_size;
1485 len = priv->ucode_init.len;
1486 IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n", 1495 IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n",
1487 len); 1496 len);
1488 memcpy(priv->ucode_init.v_addr, src, len); 1497 memcpy(priv->ucode_init.v_addr, src, len);
1498 src += len;
1489 } 1499 }
1490 1500
1491 /* Initialization data (4th block) */ 1501 /* Initialization data (4th block) */
1492 if (init_data_size) { 1502 if (init_data_size) {
1493 src = &ucode->data[inst_size + data_size + init_size]; 1503 len = init_data_size;
1494 len = priv->ucode_init_data.len;
1495 IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n", 1504 IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n",
1496 len); 1505 len);
1497 memcpy(priv->ucode_init_data.v_addr, src, len); 1506 memcpy(priv->ucode_init_data.v_addr, src, len);
1507 src += len;
1498 } 1508 }
1499 1509
1500 /* Bootstrap instructions (5th block) */ 1510 /* Bootstrap instructions (5th block) */
1501 src = &ucode->data[inst_size + data_size + init_size + init_data_size]; 1511 len = boot_size;
1502 len = priv->ucode_boot.len;
1503 IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len); 1512 IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len);
1504 memcpy(priv->ucode_boot.v_addr, src, len); 1513 memcpy(priv->ucode_boot.v_addr, src, len);
1505 1514