aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-5000.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-5000.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c111
1 files changed, 88 insertions, 23 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index a738886b434f..438e4bd0a9a8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -44,9 +44,21 @@
44#include "iwl-helpers.h" 44#include "iwl-helpers.h"
45#include "iwl-5000-hw.h" 45#include "iwl-5000-hw.h"
46 46
47#define IWL5000_UCODE_API "-1" 47/* Highest firmware API version supported */
48#define IWL5000_UCODE_API_MAX 1
49#define IWL5150_UCODE_API_MAX 1
48 50
49#define IWL5000_MODULE_FIRMWARE "iwlwifi-5000" IWL5000_UCODE_API ".ucode" 51/* Lowest firmware API version supported */
52#define IWL5000_UCODE_API_MIN 1
53#define IWL5150_UCODE_API_MIN 1
54
55#define IWL5000_FW_PRE "iwlwifi-5000-"
56#define _IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE #api ".ucode"
57#define IWL5000_MODULE_FIRMWARE(api) _IWL5000_MODULE_FIRMWARE(api)
58
59#define IWL5150_FW_PRE "iwlwifi-5150-"
60#define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode"
61#define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api)
50 62
51static const u16 iwl5000_default_queue_to_tx_fifo[] = { 63static const u16 iwl5000_default_queue_to_tx_fifo[] = {
52 IWL_TX_FIFO_AC3, 64 IWL_TX_FIFO_AC3,
@@ -338,9 +350,13 @@ static void iwl5000_gain_computation(struct iwl_priv *priv,
338 350
339 if (!data->radio_write) { 351 if (!data->radio_write) {
340 struct iwl_calib_chain_noise_gain_cmd cmd; 352 struct iwl_calib_chain_noise_gain_cmd cmd;
353
341 memset(&cmd, 0, sizeof(cmd)); 354 memset(&cmd, 0, sizeof(cmd));
342 355
343 cmd.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD; 356 cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD;
357 cmd.hdr.first_group = 0;
358 cmd.hdr.groups_num = 1;
359 cmd.hdr.data_valid = 1;
344 cmd.delta_gain_1 = data->delta_gain_code[1]; 360 cmd.delta_gain_1 = data->delta_gain_code[1];
345 cmd.delta_gain_2 = data->delta_gain_code[2]; 361 cmd.delta_gain_2 = data->delta_gain_code[2];
346 iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD, 362 iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD,
@@ -362,14 +378,19 @@ static void iwl5000_gain_computation(struct iwl_priv *priv,
362static void iwl5000_chain_noise_reset(struct iwl_priv *priv) 378static void iwl5000_chain_noise_reset(struct iwl_priv *priv)
363{ 379{
364 struct iwl_chain_noise_data *data = &priv->chain_noise_data; 380 struct iwl_chain_noise_data *data = &priv->chain_noise_data;
381 int ret;
365 382
366 if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) { 383 if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) {
367 struct iwl_calib_chain_noise_reset_cmd cmd; 384 struct iwl_calib_chain_noise_reset_cmd cmd;
368
369 memset(&cmd, 0, sizeof(cmd)); 385 memset(&cmd, 0, sizeof(cmd));
370 cmd.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD; 386
371 if (iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, 387 cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD;
372 sizeof(cmd), &cmd)) 388 cmd.hdr.first_group = 0;
389 cmd.hdr.groups_num = 1;
390 cmd.hdr.data_valid = 1;
391 ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
392 sizeof(cmd), &cmd);
393 if (ret)
373 IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n"); 394 IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n");
374 data->state = IWL_CHAIN_NOISE_ACCUMULATE; 395 data->state = IWL_CHAIN_NOISE_ACCUMULATE;
375 IWL_DEBUG_CALIB("Run chain_noise_calibrate\n"); 396 IWL_DEBUG_CALIB("Run chain_noise_calibrate\n");
@@ -415,22 +436,33 @@ static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
415 return &priv->eeprom[address]; 436 return &priv->eeprom[address];
416} 437}
417 438
439static s32 iwl5150_get_ct_threshold(struct iwl_priv *priv)
440{
441 const s32 volt2temp_coef = -5;
442 u16 *temp_calib = (u16 *)iwl_eeprom_query_addr(priv,
443 EEPROM_5000_TEMPERATURE);
444 /* offset = temperate - voltage / coef */
445 s32 offset = temp_calib[0] - temp_calib[1] / volt2temp_coef;
446 s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD) - offset;
447 return threshold * volt2temp_coef;
448}
449
418/* 450/*
419 * Calibration 451 * Calibration
420 */ 452 */
421static int iwl5000_set_Xtal_calib(struct iwl_priv *priv) 453static int iwl5000_set_Xtal_calib(struct iwl_priv *priv)
422{ 454{
423 u8 data[sizeof(struct iwl_calib_hdr) + 455 struct iwl_calib_xtal_freq_cmd cmd;
424 sizeof(struct iwl_cal_xtal_freq)];
425 struct iwl_calib_cmd *cmd = (struct iwl_calib_cmd *)data;
426 struct iwl_cal_xtal_freq *xtal = (struct iwl_cal_xtal_freq *)cmd->data;
427 u16 *xtal_calib = (u16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL); 456 u16 *xtal_calib = (u16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL);
428 457
429 cmd->hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD; 458 cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD;
430 xtal->cap_pin1 = (u8)xtal_calib[0]; 459 cmd.hdr.first_group = 0;
431 xtal->cap_pin2 = (u8)xtal_calib[1]; 460 cmd.hdr.groups_num = 1;
461 cmd.hdr.data_valid = 1;
462 cmd.cap_pin1 = (u8)xtal_calib[0];
463 cmd.cap_pin2 = (u8)xtal_calib[1];
432 return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL], 464 return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL],
433 data, sizeof(data)); 465 (u8 *)&cmd, sizeof(cmd));
434} 466}
435 467
436static int iwl5000_send_calib_cfg(struct iwl_priv *priv) 468static int iwl5000_send_calib_cfg(struct iwl_priv *priv)
@@ -466,6 +498,9 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv,
466 * uCode. iwl_send_calib_results sends them in a row according to their 498 * uCode. iwl_send_calib_results sends them in a row according to their
467 * index. We sort them here */ 499 * index. We sort them here */
468 switch (hdr->op_code) { 500 switch (hdr->op_code) {
501 case IWL_PHY_CALIBRATE_DC_CMD:
502 index = IWL_CALIB_DC;
503 break;
469 case IWL_PHY_CALIBRATE_LO_CMD: 504 case IWL_PHY_CALIBRATE_LO_CMD:
470 index = IWL_CALIB_LO; 505 index = IWL_CALIB_LO;
471 break; 506 break;
@@ -802,6 +837,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
802 } 837 }
803 838
804 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; 839 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
840 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
805 priv->hw_params.scd_bc_tbls_size = 841 priv->hw_params.scd_bc_tbls_size =
806 IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl); 842 IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl);
807 priv->hw_params.max_stations = IWL5000_STATION_COUNT; 843 priv->hw_params.max_stations = IWL5000_STATION_COUNT;
@@ -845,7 +881,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
845 case CSR_HW_REV_TYPE_5150: 881 case CSR_HW_REV_TYPE_5150:
846 /* 5150 wants in Kelvin */ 882 /* 5150 wants in Kelvin */
847 priv->hw_params.ct_kill_threshold = 883 priv->hw_params.ct_kill_threshold =
848 CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD); 884 iwl5150_get_ct_threshold(priv);
849 break; 885 break;
850 } 886 }
851 887
@@ -862,7 +898,12 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
862 BIT(IWL_CALIB_BASE_BAND); 898 BIT(IWL_CALIB_BASE_BAND);
863 break; 899 break;
864 case CSR_HW_REV_TYPE_5150: 900 case CSR_HW_REV_TYPE_5150:
865 priv->hw_params.calib_init_cfg = 0; 901 priv->hw_params.calib_init_cfg =
902 BIT(IWL_CALIB_DC) |
903 BIT(IWL_CALIB_LO) |
904 BIT(IWL_CALIB_TX_IQ) |
905 BIT(IWL_CALIB_BASE_BAND);
906
866 break; 907 break;
867 } 908 }
868 909
@@ -1501,7 +1542,9 @@ static struct iwl_mod_params iwl50_mod_params = {
1501 1542
1502struct iwl_cfg iwl5300_agn_cfg = { 1543struct iwl_cfg iwl5300_agn_cfg = {
1503 .name = "5300AGN", 1544 .name = "5300AGN",
1504 .fw_name = IWL5000_MODULE_FIRMWARE, 1545 .fw_name_pre = IWL5000_FW_PRE,
1546 .ucode_api_max = IWL5000_UCODE_API_MAX,
1547 .ucode_api_min = IWL5000_UCODE_API_MIN,
1505 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 1548 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
1506 .ops = &iwl5000_ops, 1549 .ops = &iwl5000_ops,
1507 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 1550 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
@@ -1512,7 +1555,9 @@ struct iwl_cfg iwl5300_agn_cfg = {
1512 1555
1513struct iwl_cfg iwl5100_bg_cfg = { 1556struct iwl_cfg iwl5100_bg_cfg = {
1514 .name = "5100BG", 1557 .name = "5100BG",
1515 .fw_name = IWL5000_MODULE_FIRMWARE, 1558 .fw_name_pre = IWL5000_FW_PRE,
1559 .ucode_api_max = IWL5000_UCODE_API_MAX,
1560 .ucode_api_min = IWL5000_UCODE_API_MIN,
1516 .sku = IWL_SKU_G, 1561 .sku = IWL_SKU_G,
1517 .ops = &iwl5000_ops, 1562 .ops = &iwl5000_ops,
1518 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 1563 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
@@ -1523,7 +1568,9 @@ struct iwl_cfg iwl5100_bg_cfg = {
1523 1568
1524struct iwl_cfg iwl5100_abg_cfg = { 1569struct iwl_cfg iwl5100_abg_cfg = {
1525 .name = "5100ABG", 1570 .name = "5100ABG",
1526 .fw_name = IWL5000_MODULE_FIRMWARE, 1571 .fw_name_pre = IWL5000_FW_PRE,
1572 .ucode_api_max = IWL5000_UCODE_API_MAX,
1573 .ucode_api_min = IWL5000_UCODE_API_MIN,
1527 .sku = IWL_SKU_A|IWL_SKU_G, 1574 .sku = IWL_SKU_A|IWL_SKU_G,
1528 .ops = &iwl5000_ops, 1575 .ops = &iwl5000_ops,
1529 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 1576 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
@@ -1534,7 +1581,9 @@ struct iwl_cfg iwl5100_abg_cfg = {
1534 1581
1535struct iwl_cfg iwl5100_agn_cfg = { 1582struct iwl_cfg iwl5100_agn_cfg = {
1536 .name = "5100AGN", 1583 .name = "5100AGN",
1537 .fw_name = IWL5000_MODULE_FIRMWARE, 1584 .fw_name_pre = IWL5000_FW_PRE,
1585 .ucode_api_max = IWL5000_UCODE_API_MAX,
1586 .ucode_api_min = IWL5000_UCODE_API_MIN,
1538 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 1587 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
1539 .ops = &iwl5000_ops, 1588 .ops = &iwl5000_ops,
1540 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 1589 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
@@ -1545,7 +1594,22 @@ struct iwl_cfg iwl5100_agn_cfg = {
1545 1594
1546struct iwl_cfg iwl5350_agn_cfg = { 1595struct iwl_cfg iwl5350_agn_cfg = {
1547 .name = "5350AGN", 1596 .name = "5350AGN",
1548 .fw_name = IWL5000_MODULE_FIRMWARE, 1597 .fw_name_pre = IWL5000_FW_PRE,
1598 .ucode_api_max = IWL5000_UCODE_API_MAX,
1599 .ucode_api_min = IWL5000_UCODE_API_MIN,
1600 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
1601 .ops = &iwl5000_ops,
1602 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
1603 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
1604 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
1605 .mod_params = &iwl50_mod_params,
1606};
1607
1608struct iwl_cfg iwl5150_agn_cfg = {
1609 .name = "5150AGN",
1610 .fw_name_pre = IWL5150_FW_PRE,
1611 .ucode_api_max = IWL5150_UCODE_API_MAX,
1612 .ucode_api_min = IWL5150_UCODE_API_MIN,
1549 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 1613 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
1550 .ops = &iwl5000_ops, 1614 .ops = &iwl5000_ops,
1551 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 1615 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
@@ -1554,7 +1618,8 @@ struct iwl_cfg iwl5350_agn_cfg = {
1554 .mod_params = &iwl50_mod_params, 1618 .mod_params = &iwl50_mod_params,
1555}; 1619};
1556 1620
1557MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE); 1621MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
1622MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX));
1558 1623
1559module_param_named(disable50, iwl50_mod_params.disable, int, 0444); 1624module_param_named(disable50, iwl50_mod_params.disable, int, 0444);
1560MODULE_PARM_DESC(disable50, 1625MODULE_PARM_DESC(disable50,