aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-5000.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2008-09-02 23:26:37 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-08 14:23:18 -0400
commit6e21f2c109edd746a10e08186484bae8168cdd0c (patch)
treeb006657b3a64edd05fc8b568b4241dc3617ec5d5 /drivers/net/wireless/iwlwifi/iwl-5000.c
parent7c95168aba66bd11bf9efaf45e16e83ae869401d (diff)
iwlwifi: generic init calibrations framework
This patch allows variable number of init calibrations and allows addition new HW. This patch also fixes critical bug. Only last calibration result was applied. On reception of one calibration result all the calibration was freed. Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-5000.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c63
1 files changed, 9 insertions, 54 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index cbc01a00eaf4..8b6a72949ac0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -444,48 +444,6 @@ static int iwl5000_send_Xtal_calib(struct iwl_priv *priv)
444 sizeof(cal_cmd), &cal_cmd); 444 sizeof(cal_cmd), &cal_cmd);
445} 445}
446 446
447static int iwl5000_send_calib_results(struct iwl_priv *priv)
448{
449 int ret = 0;
450
451 struct iwl_host_cmd hcmd = {
452 .id = REPLY_PHY_CALIBRATION_CMD,
453 .meta.flags = CMD_SIZE_HUGE,
454 };
455
456 if (priv->calib_results.lo_res) {
457 hcmd.len = priv->calib_results.lo_res_len;
458 hcmd.data = priv->calib_results.lo_res;
459 ret = iwl_send_cmd_sync(priv, &hcmd);
460
461 if (ret)
462 goto err;
463 }
464
465 if (priv->calib_results.tx_iq_res) {
466 hcmd.len = priv->calib_results.tx_iq_res_len;
467 hcmd.data = priv->calib_results.tx_iq_res;
468 ret = iwl_send_cmd_sync(priv, &hcmd);
469
470 if (ret)
471 goto err;
472 }
473
474 if (priv->calib_results.tx_iq_perd_res) {
475 hcmd.len = priv->calib_results.tx_iq_perd_res_len;
476 hcmd.data = priv->calib_results.tx_iq_perd_res;
477 ret = iwl_send_cmd_sync(priv, &hcmd);
478
479 if (ret)
480 goto err;
481 }
482
483 return 0;
484err:
485 IWL_ERROR("Error %d\n", ret);
486 return ret;
487}
488
489static int iwl5000_send_calib_cfg(struct iwl_priv *priv) 447static int iwl5000_send_calib_cfg(struct iwl_priv *priv)
490{ 448{
491 struct iwl5000_calib_cfg_cmd calib_cfg_cmd; 449 struct iwl5000_calib_cfg_cmd calib_cfg_cmd;
@@ -510,33 +468,30 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv,
510 struct iwl_rx_packet *pkt = (void *)rxb->skb->data; 468 struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
511 struct iwl5000_calib_hdr *hdr = (struct iwl5000_calib_hdr *)pkt->u.raw; 469 struct iwl5000_calib_hdr *hdr = (struct iwl5000_calib_hdr *)pkt->u.raw;
512 int len = le32_to_cpu(pkt->len) & FH_RSCSR_FRAME_SIZE_MSK; 470 int len = le32_to_cpu(pkt->len) & FH_RSCSR_FRAME_SIZE_MSK;
513 471 int index;
514 iwl_free_calib_results(priv);
515 472
516 /* reduce the size of the length field itself */ 473 /* reduce the size of the length field itself */
517 len -= 4; 474 len -= 4;
518 475
476 /* Define the order in which the results will be sent to the runtime
477 * uCode. iwl_send_calib_results sends them in a row according to their
478 * index. We sort them here */
519 switch (hdr->op_code) { 479 switch (hdr->op_code) {
520 case IWL5000_PHY_CALIBRATE_LO_CMD: 480 case IWL5000_PHY_CALIBRATE_LO_CMD:
521 priv->calib_results.lo_res = kzalloc(len, GFP_ATOMIC); 481 index = IWL5000_CALIB_LO;
522 priv->calib_results.lo_res_len = len;
523 memcpy(priv->calib_results.lo_res, pkt->u.raw, len);
524 break; 482 break;
525 case IWL5000_PHY_CALIBRATE_TX_IQ_CMD: 483 case IWL5000_PHY_CALIBRATE_TX_IQ_CMD:
526 priv->calib_results.tx_iq_res = kzalloc(len, GFP_ATOMIC); 484 index = IWL5000_CALIB_TX_IQ;
527 priv->calib_results.tx_iq_res_len = len;
528 memcpy(priv->calib_results.tx_iq_res, pkt->u.raw, len);
529 break; 485 break;
530 case IWL5000_PHY_CALIBRATE_TX_IQ_PERD_CMD: 486 case IWL5000_PHY_CALIBRATE_TX_IQ_PERD_CMD:
531 priv->calib_results.tx_iq_perd_res = kzalloc(len, GFP_ATOMIC); 487 index = IWL5000_CALIB_TX_IQ_PERD;
532 priv->calib_results.tx_iq_perd_res_len = len;
533 memcpy(priv->calib_results.tx_iq_perd_res, pkt->u.raw, len);
534 break; 488 break;
535 default: 489 default:
536 IWL_ERROR("Unknown calibration notification %d\n", 490 IWL_ERROR("Unknown calibration notification %d\n",
537 hdr->op_code); 491 hdr->op_code);
538 return; 492 return;
539 } 493 }
494 iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len);
540} 495}
541 496
542static void iwl5000_rx_calib_complete(struct iwl_priv *priv, 497static void iwl5000_rx_calib_complete(struct iwl_priv *priv,
@@ -834,7 +789,7 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
834 iwl5000_send_Xtal_calib(priv); 789 iwl5000_send_Xtal_calib(priv);
835 790
836 if (priv->ucode_type == UCODE_RT) 791 if (priv->ucode_type == UCODE_RT)
837 iwl5000_send_calib_results(priv); 792 iwl_send_calib_results(priv);
838 793
839 return 0; 794 return 0;
840} 795}